Il pilotaggio di motori sincroni a magneti permanenti o Pmsm (Permanent Magnet Synchronous Motor) basato su tecniche di controllo vettoriale come il Foc (Field Oriented Control) è indispensabile per tutti quei progetti che devono garantire prestazioni ottimali dal punto di vista dell'efficienza energetica e della dinamica di controllo. I core più venduti di Arm, come l'onnipresente Cortex-M3, offrono una potenza di calcolo sufficiente per le funzioni necessarie; spesso si possono prendere carico anche di implementare gli algoritmi matematici necessari per rilevare la posizione angolare del rotore mentre il motore sta funzionando, dando quindi la possibilità di eliminare i sensori di velocità (in questo caso si parla di sistemi sensorless). Un microcontrollore basato su Cortex-M3 a 24 MHz, come l’STM32F100, raggiunge i 30 Dmips: una potenza sufficiente ad esempio per il pilotaggio sensorless della silenziosa pompa tri-fase di una lavastoviglie con Pwm a 16 kHz, Foc a 8 kHz. In questo caso rimane addirittura a disposizione il 47% della potenza di calcolo della Cpu per eventuali altre funzioni. È abbastanza facile immaginare che un Cortex-M3 a 72 MHz (come l’STM32F103), o addirittura a 120 MHz (come l’STM32F2x), possano offrire una potenza ancora superiore candidandosi per il pilotaggio sensorless Foc di due Pmsm. A questo punto la domanda è: ne vale la pena, è conveniente realizzare un progetto con un solo Mcu che pilota due motori?
Di fatto, questa soluzione ha molti vantaggi e permette di ridurre il costo finale dell'applicazione. È molto probabile, per esempio, che le dimensioni della memoria Flash non debbano raddoppiare. Si risparmia spazio e si riduce il numero di piste stampato sul Pcb. Addirittura un microcontrollore con 64 piedini può essere sufficiente: ogni motore ha infatti bisogno di 3+3 uscite Pwm, 1 ingresso di emergenza, fino a 3 ingressi analogici per la lettura della corrente e fino a 2 per la lettura della tensione del bus Dc e del feedback di temperatura, 3 ingressi digitali per la lettura del sensore di velocità (se necessario). Si diminuisce il numero di componenti esterni. Il consumo di corrente della sezione digitale, sia in funzionamento che a riposo, si dimezza (permettendo la riduzione dei costi della sezione di alimentazione). Gli sforzi per ottenere la certificazione dell'apparecchiatura in base alle norme IEC 60335-1 Class B si possono concentrare su un solo microcontrollore. Si semplifica lo sviluppo del livello applicativo necessario per coordinare le attività dei motori e infine si utilizza un'unica catena di strumenti di sviluppo. D’altra parte si può pensare che una soluzione con due microcontrollori offra una ridondanza di risorse che, in linea di principio, è sinonimo di una maggiore affidabilità. Tuttavia questo vantaggio rimane solo sulla carta, nel caso di applicazioni in cui ciascuno dei due motori non può funzionare indipendentemente dall'altro. Si consideri per esempio un impianto per il condizionamento degli ambienti: in caso di guasto del sistema di pilotaggio della ventola esterna, l'apparecchiatura non è utilizzabile, anche se il compressore non presenta problemi, e viceversa. Ragionamenti analoghi si possono fare per una lavatrice che è comunque inutilizzabile anche se il motore della pompa di scarico non ha problemi, ma è bloccato il cestello.
Il doppio controllo vettoriale
Nell’implementazione pratica di un doppio controllo vettoriale, esistono diverse problematiche da affrontare. Innanzitutto un doppio sistema di pilotaggio Foc è ovviamente più facile da realizzare se le periferiche integrate sono progettate specificatamente per questo scopo e quindi permettono di affrontare più facilmente alcune possibili criticità software. Per quanto riguarda i requisiti indispensabili per il microcontrollore, è chiara la necessità di disporre di due “timer avanzati”. Ognuno deve essere in grado di generare 6 segnali Pwm (high side e low side complementati tramite l’inserimento di tempi morti), reagire a segnali di guasto – anche in presenza di un malfunzionamento dell’oscillatore di clock – e portare l’uscita del timer in stato di reset o in uno stato configurabile conosciuto, oltre a fornire la circuiteria di sincronizzazione necessaria per attivare le periferiche Adc in qualunque momento durante il periodo Pwm. Inoltre, sono necessarie almeno tre periferiche indipendenti Adc, in particolare quando la configurazione hardware del sistema prevede una topologia con tre resistori shunt per leggere le correnti del primo motore (con riferimento ad STM32, sono sufficienti due Adc dedicati che operano in modalità ‘injected simultaneous’) e un unico resistore shunt sul bus DC per leggere le correnti del secondo motore (con riferimento ad STM32 un Adc dedicato che opera in modalità ‘injected discontinuous’). In realtà è anche possibile realizzare una configurazione duale con tre resistori shunt utilizzando solo due periferiche Adc a patto di implementare un'adeguata condivisione delle risorse tra i due sistemi di pilotaggio. Quando si affronta il problema della condivisione delle risorse, è fondamentale allocare adeguatamente il tempo della Cpu alle diverse attività necessarie per il pilotaggio Foc del motore: il sistema di pilotaggio Foc “sensorless” lavora a frequenze relativamente elevate (fino a circa 16 kHz, per esempio, nel caso di una lavatrice), i tempi di esecuzione sono estremamente critici e devono essere sincroni con il relativo periodo Pwm. Ciò pone un limite alle possibili configurazioni e obbliga a effettuare alcune scelte precise in fase di progettazione: i due sistemi di pilotaggio devono avere frequenze Pwm il cui rapporto deve essere rappresentato da un numero intero; i due timer devono essere sincronizzati in modo che gli eventi di update non si sovrappongano.
Lo sviluppo del software
Infine, da non sottovalutare, esiste il rischio di affrontare uno sviluppo software piuttosto complesso e vincolato alle specifiche dettate dal progetto di un particolare prodotto, ma che non potrà poi essere facilmente riutilizzato per configurazioni diverse. In questo caso, il problema può essere evitato realizzando una robusta struttura firmware in grado di offrire dei vantaggi anche nel caso in cui sia presente un solo motore e che risulti poi estremamente efficiente, per dimensioni del codice programma, in situazioni in cui si usino prevalentemente architetture con due motori.
Partendo da questi presupposti, STMicroelectronics ha progettato il suo Pmsm Foc Software Development Kit in modo da permettere la più ampia scelta possibile tra configurazioni diverse: l'architettura e il firmware sono scalabili e si adattano a tutta la famiglia STM32, dall’F10x all’ F2x. Possono adeguarsi a differenti esigenze hardware (motori di diversa potenza, differenti sensori di corrente e di velocità), differenti algoritmi (sensorless basati su State Observer, Pll, Cordic, ottimizzazione dell'efficienza I-Pmsm) per il controllo di uno o due motori. Un elemento fondamentale, alla base dell’SDK, è la ristrutturazione concettuale del controllo del motore utilizzando un approccio di tipo Object Oriented Modeling. Il C++ è un linguaggio di programmazione che ne integra e ottimizza i concetti di base, che sono però assolutamente generici e possono essere implementati utilizzando qualunque linguaggio di programmazione, ad esempio il C standard come nel caso in esame. In effetti, le tecniche di Object Oriented Analysis che costituiscono il passo che precede l’Object Oriented Programming, sono state utilizzate per affrontare e modellizzare il sistema del punto di vista dei rapporti interni/esterni, delle strutture dei dati e delle funzioni necessarie. Un sistema di controllo del motore, per esempio, prevede tipicamente la presenza di sensori di velocità utilizzati per misurare la velocità del motore (e chiudere quindi l’anello di retroazione necessario per il controllo della velocità) e l’angolo del rotore (per implementare un algoritmo di controllo vettoriale). In genere, se si applica l’approccio della Programmazione Procedurale (Procedural Programming) la libreria per il controllo del motore conterrà “moduli” software specializzati per la decodifica dei sensori. Sarà presente un modulo per ognuna delle cinque tipologie più usate: encoder, Hall, sensorless, resolver, tachometer. Quindi le stesse azioni, per esempio ‘GetSpeed’ o ‘GetAngle’ dovranno essere realizzate da cinque diverse funzioni, implementate ciascuna in modo differente e con differenti strutture dei dati e nomi diversi (il nome di solito dipende dal modulo a cui appartengono).
Proviamo ad analizzare le conseguenze di questo approccio tradizionale. Nel caso di un sistema per il pilotaggio di un unico motore, l'implementazione è relativamente semplice ed è possibile ottimizzare le dimensioni del codice. D'altra parte, nel caso di sistemi per il pilotaggio di due o più motori, la situazione è decisamente più complessa poiché le funzioni comuni a tutti i membri della famiglia probabilmente non sono state isolate. Inoltre, a causa delle diverse interfacce, l'integrazione dei moduli con altre entità è relativamente rigida sia vista dall’alto (utente finale) che dal basso (relazione con altri moduli). Il cambiamento di alcuni parametri di configurazione del sistema (per esempio sensori di corrente/velocità) è piuttosto complesso e richiede la presenza di un buon numero di istruzioni condizionali in fase di pre-processing o di “switch” condizionali nella fase di esecuzione.
Il passaggio a una tecnica di Object Oriented Modeling permette di definire una classe, ad esempio quella dei sensori di velocità, che comprende “oggetti” con parametri o proprietà diverse (per esempio la massima velocità accettabile oltre la quale è necessario segnalare una condizione di malfunzionamento, il rapporto angolare elettrico/meccanico, la larghezza di banda dei filtri digitali applicati). Ogni oggetto comprende al suo interno (‘encapsulation’) una struttura dati relativa al suo stato e offre all'esterno un'interfaccia, cioè la lista delle funzioni o “metodi” che possono essere applicati sulla stessa struttura dati. Classi successive possono essere derivate da una classe di base, creando un rapporto gerarchico tra una “classe genitore (parent class)” e una “classe figlio (child class)” che prevede che la struttura dei dati e i metodi del genitore siano “ereditati” dal figlio. Inoltre, le classi derivate possono aggiungere nuovi metodi, specifici e intrinseci alla propria natura, o differenziare il proprio comportamento (polimorfismo) rispetto a quello ereditato dalla classe di base.
Tornando al nostro esempio, sarà possibile definire un oggetto appartenente alla classe “Speed Sensorless State Observer” (osservatore di stato della velocità, senza far uso di sensori) derivata dalla classe “Speed sensor” (sensori di velocità): una volta che l'oggetto è stato creato, non è necessario che gli utenti ne conoscano con precisione il tipo (state observer, osservatore di stato, o encoder). È sufficiente invocare i metodi della classe base; il comportamento sarà quindi diverso in relazione alle caratteristiche specifiche dell'oggetto (cioè in relazione alla classe derivata cui l’oggetto appartiene). I vantaggi di questo modello di programmazione orientato agli oggetti sono evidenti: il polimorfismo facilita la creazione di rapporti complessi tra le diverse classi, semplificando notevolmente la configurabilità del sistema. Si riducono le dimensioni del codice di programma quando si creano due o più oggetti della stessa classe (base o derivata). La ‘encapsulation’ garantisce la robustezza del codice programma, poiché i dati sono accessibili solo attraverso i metodi predefiniti ed è quindi impossibile modificare accidentalmente le variabili dell'oggetto. La semplicità di utilizzo (garantita dal livello di astrazione che si riesce ad ottenere) è tale da permettere di conoscere semplicemente l'interfaccia senza doversi preoccupare dei dettagli implementativi, concentrandosi quindi sullo sviluppo del software specifico per l'applicazione. Diventa più facile ampliare e mantenere la libreria, ed è più semplice aggiungere una nuova classe o modificarla, sfruttando ciò che è già stato realizzato e implementato nella classe genitore (parent class). La libreria ‘MC Library’ (Motor Control Library) è l'elemento centrale del software development kit STM32 FOC PMSM. Modellizzata e implementata utilizzando l'approccio Oop (Object Oriented Programming), la libreria è scritta in un linguaggio Ansi C ed è composta da 32 classi, tra base e derivate, che forniscono tutti gli elementi funzionali necessari: Foc e derivati (deflussaggio, regolazione della corrente in feed forward, ottimizzazioni per I-PMSM), sensori di corrente (uno shunt, tre shunt, sensori isolati), sensori di velocità (sensorless, Hall, encoder), controllori di velocità o coppia, sensori di temperatura. Il livello superiore (‘MC application’) presenta verso l’esterno la propria Api (Application Programming Interface): comandi ad alto livello, come Start Motor (fai partire il motore), Stop Motor (ferma il motore), Execute Speed Ramp (incrementa/decrementa linearmente la velocità), Get State (leggi lo stato del sistema) ne facilitano l'integrazione con il progetto dell'utente. La MC application, al suo interno, durante la fase di boot crea gli oggetti necessari partendo dalla libreria ed in base ai parametri effettivi del sistema (descritti utilizzando uno strumento grafico di configurazione su Pc, l’ST Motor Control Workbench). Li coordina poi con continuità nel tempo per rispondere adeguatamente ai comandi ricevuti, tramite “task” di priorità e periodicità adeguate. Per i task che devono essere realizzati nella fase di esecuzione e funzionamento serve evidentemente una temporizzazione precisa che, nell'architettura dell’STM32 PMSM FOC SDK, utilizza alcune funzioni di ‘clock’ chiamate dall’esterno. È stato realizzato un semplice scheduler (sistema di pianificazione temporale degli eventi), basato sul Cortex-M3 Systick timer (handler Systick e Pended System Call) che viene presentato in un progetto dimostrativo, come esempio. Contemporaneamente, un altro progetto dimostrativo illustra come sia possibile, con uno sforzo minimo, configurare un sistema operativo in tempo reale (per esempio il FreeRTOS OS). In questo caso i vantaggi, a fronte di una memoria Flash di dimensioni un po’ maggiori (2,3 kB), sono i servizi configurabili e la provata affidabilità dello scheduler del sistema operativo che possono essere utili per il progetto: task, code, semafori, mutex. Come risulta dall'analisi, i nuovi microcontrollori come l’STM32F1x e STM32F2x basati su “core” Cortex-M3, sono decisamente più che sufficienti per pilotare due motori utilizzando la tecnica FOC sensorless (senza sensori). La pratica implementabilità di questa architettura, alla fine, dipende molto dalle strutture software e dalle periferiche integrate.