Vai al contenuto
PLC Forum


Motore BLDC lavatrice LG


marcoc4d

Messaggi consigliati

14 ore fa, marcoc4d scrisse:

 

ho modificato la libreria del pid facendola in virgola fissa e le cose sono migliorate parecchio,

 

Il problema è che rischi di perdere in precisione, specialmente per l'integrale.

Link al commento
Condividi su altri siti


  • Risposte 159
  • Created
  • Ultima risposta

Top Posters In This Topic

  • marcoc4d

    71

  • Sandro Calligaro

    62

  • Livio Orsini

    19

  • zhavinchi1

    4

Sandro Calligaro

Con il giusto numero di bit frazionari, credo che si possa facilmente raggiungere la precisione richiesta.

Come dice Livio, però, gli incrementi dell'integrale possono diventare troppo piccoli (a seconda del guadagno impostato), perciò bisogna magari usare più bit frazionari per alcune variabili.

 

Normalmente, nel controllo motore (o praticamente dovunque si usi un ADC a 12 bit), per evitare problemi si usano numeri frazionari Q8.24, cioè 32 bit di cui 24 dopo la virgola. Nonostante questo, in alcuni casi occorre aumentare ulteriormente il numero di bit frazionari, per specifiche variabili.

 

In generale, l'uso della virgola fissa sembra una cosa molto semplice, ma purtroppo non lo è.

Qualche link per chiarire:

https://en.wikipedia.org/wiki/Q_(number_format)

http://read.pudn.com/downloads227/doc/1065342/IQmath.pdf

https://www.mathworks.com/help/supportpkg/texasinstrumentsc2000/ug/using-the-iqmath-library.html

 

Un esempio che ho (passa-basso e passa-alto del primo ordine):

 

// parameters for LPF and HPF
#define F_CORNER      1.0                                        // corner frequency of the filter (must be < PWM_FREQ/2 !)
#define Ts_tau        (1.0/PWM_FREQ / ( 1/(2.0*3.1416 * F_CORNER))) // filter coefficient Ts/tau, corresponding to approximately F_CORNER [Hz]

// check that Ts_tau is not too large (<2) nor too low (<=0)
#define QVALUE        14                                          // number of bits for the fractional part
long filter_coeff = Ts_tau * (1<<QVALUE);                         // actual filter coefficient (scaled with QVALUE)
int in = 0;           // filter input
long x_LPF_32 = 0;    // LPF 32-bit accumulator
int x_LPF = 0;        // LPF output (16-bit: Q1.14)
int x_HPF = 0;        // HPF output (16-bit: Q1.14)

 

// [ Other code here ... ]

 

// Within the Interrupt Service Routine
  // LPF and HPF (takes approximately 16 us)
  x_LPF_32 += (in - x_LPF) * (long)filter_coeff;  // calculate LPF(x) (32-bit)
  x_LPF = (int)(x_LPF_32>>14);                    // calculate LPF(x) (16-bit: Q1.14) >> bitshift
  x_HPF = in - x_LPF;                             // calculate HPF(x) (16-bit: Q1.14)

 

 

 

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

Sandro Calligaro

Non mi ricordavo di avere anche un esempio di controllo PI in floating-point (per Arduino UNO), che viene aggiornato ogni 3 cicli di PWM (switching a 20 kHz).

Anche qui, lo scopo era didattico (con 20 kHz, tra l'altro, i valori di L e C sono relativamente molto grandi).

 

E' un po' tirato come tempi (rimane poco spazio per fare altro), e bisogna verificare sempre con l'oscilloscopio di rimanere con l'esecuzione dentro il periodo (in questo caso, guardando l'impulso sul pin 5, con oscilloscopio in persistenza infinita, se possibile).

 

NB: interruptPWM.h è una mia "libreria", con due funzioni per impostare l'ADC (ADCinit) la PWM e l'interrupt (PWMinit), oltre che imporre il duty-cycle (writePWM1 e 2).

 

 

// CONTROL OF BUCK CONVERTER
// with L298 half-bridge and L-C filter, controlled by Arduino.
// Switching frequency is meant to be set in the range 5-20 kHz.
//
// The control algorithm (voltage PI control) is split into N parts, executed in a sequence.
// Each part of the control algorithm is carried out in one interrupt call.
//
// The PWM output pin (Arduino digital pin 10) cannot be changed, since the Timer1 is used.

 

// include fast PWM, interrupts and ADC "library"
#include "interruptPWM.h"

 

#define CLK_FREQ    (16.0e6)              // system clock frequency [Hz]
#define PWM_FREQ    (20.0e3)              // PWM frequency [Hz]
#define PERIOD      (CLK_FREQ/PWM_FREQ/2.0) // PMW counts (up, down) [Hz] (e.g. Fsw = 20 kHz if PERIOD==400)
#define N           3.0                   // undersampling ratio (sampling frequency / PWM frequency)
#define SAMPLE_FREQ (PWM_FREQ/N)          // control sampling frequency [Hz]
#define Ts          (1/SAMPLE_FREQ)       // control sampling period
#define ADC_COUNTS  1023.0                // ADC full-scale [count]

#define SERIAL_BAUD_RATE    2e6           // serial port baudrate [bit/s]
#define SERIAL_TIMEOUT      100           // serial port timeout [ms]

 

// physical values
#define V_IN          12.0                // input DC voltage [V]
#define V_FS          5.0                 // real full-scale ADC input voltage [V]
#define DIV_RATIO_V   3.0                 // voltage feedback network divider ratio
#define ADC2VOLT      (V_FS*DIV_RATIO_V/ADC_COUNTS);    // ADC voltage conversion factor (Vout_fdb = Vout_fdb_raw*ADC2VOLT)

 

// input and output pins
#define I2            10                  // Input2 pin L298
#define EA            11                  // EnableA pin L298
#define STROBE        5                   // strobe output (execution monitoring)

 

// algorithm sequence states
#define ACQUIRE       0                   // ADC acquisition state
#define UPDATE1       1                   // first part of PI algorithm
#define UPDATE2       2                   // second part of PI algorithm

byte ISRtask = ACQUIRE; // current state of algorithm sequence

float Vout_ref = 0;           // output voltage setpoint (input from serial monitor) [V] (0-12V)
float Vout_fdb_raw = 0;       // output voltage feedback ADC value [count] (0-1023)
float Vout_fdb = 0;           // output voltage feedback
float V_err = 0;              // voltage error, PI input [V]
float x_int = 0.0;            // PI integral part (memory) [counts]
float compare = 0;            // PWM compare value, PI output [count] (0-PERIOD)

 

// PI controller parameters
#define CTRL_BW       100.0                                 // desired control bandwidth [Hz]
#define SQRT_LC       (2.17e-4)                             // sqrt(L*C)
#define Kp            (2.0*PI*CTRL_BW*PERIOD/V_IN*SQRT_LC)  // proportional gain, norm. with V_IN  ( Kp = 2*pi*CTRL_BW*sqrt(L*C) *PERIOD)
#define Ki            (Kp/SQRT_LC)                          // integral gain, norm. with V_IN      ( tau_PI = Kp/Ki = sqrt(L*C) )
#define KiTs          (Ki*Ts)                               // integral increment factor

 

 

void setup() {
 
  digitalWrite(EA, 0);      // start with H-bridge disabled
 
  Serial.begin(SERIAL_BAUD_RATE);     // set serial for fastest communication rate (set the same in serial monitor!)
  Serial.setTimeout(SERIAL_TIMEOUT);  // set serial port timeout [ms]

  ADCinit();                // ADC configuration
  PWMinit(PERIOD);          // PWM and interrupt configuration

  pinMode(STROBE, OUTPUT);  // set STROBE pin as output
  pinMode(EA, OUTPUT);      // set EA pin as output
  pinMode(A0, INPUT);
   
  digitalWrite(EA, 1);      // start with H-bridge enabled

}

/////////////////////////////////////////////////////////////////////////////
// Timer 1 overflow interrupt service routine
// This function is executed each PWM period
// Each part of the control algorithm is executed once every 3 PWM periods
ISR(TIMER1_OVF_vect) {
 
  digitalWrite(STROBE,1);   // raise strobe pin

  // this part is executed at the 1st of 3 PWM periods
  if (ISRtask == ACQUIRE)
  {
    Vout_fdb_raw = analogRead(A0);      // read Vout (raw value) from ADC
    Vout_fdb = Vout_fdb_raw*ADC2VOLT;   // calculate feedback value [V]
    
    ISRtask = UPDATE1;                  // jump to next part of the algorithm
  }

  // this part is executed at the 2nd of 3 PWM periods
  else if (ISRtask == UPDATE1)
  {
    V_err = Vout_ref - Vout_fdb;        // calculate the control error [V]
    
    x_int = x_int + KiTs*V_err;         // calculate the integral part
    x_int = constrain(x_int,0.0,PERIOD);// apply limits to PI integral part

    ISRtask = UPDATE2;                  // jump to next part of the algorithm
  }

  // this part is executed at the 3rd of 3 PWM periods
  else if (ISRtask == UPDATE2)
  {
    compare = Kp*V_err + x_int;         // update PI output (compare)
    compare = constrain(compare,0.0,PERIOD);      // apply limits to PMW compare
    
    writePWM2(compare);                 // write PWM compare value

    ISRtask = ACQUIRE;                  // jump to next part of the algorithm
  }
 
  digitalWrite(STROBE,0);   // lower strobe pin
}

/////////////////////////////////////////////////////////////////////////////

 

// this sequence repeats asynchronously (non real-time)
void loop() {

  // read setpoint value from serial port
  if (Serial.available()>0)
  {
    Vout_ref = Serial.parseFloat();
  }  

  // send values on serial port
  Serial.print(Vout_ref); Serial.print(" ");
  Serial.print(Vout_fdb); Serial.print(" ");
  Serial.print(compare);  Serial.println(" ");

  /*
  Serial.print(Kp);Serial.print(" ");
  Serial.print(Ki);Serial.print(" ");
  Serial.print(Ts*1e6);Serial.println(" us");
  */
}

 

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

58 minuti fa, Sandro Calligaro scrisse:

che viene aggiornato ogni 3 cicli di PWM (switching a 20 kHz).

 

A me questa soluzione piace poco, io preferisco avere sempre un timer dedicato solo per il richiamo del PID. L'eventuale jitter dovuto alla non sincronizzazione della correzione con la frequenza di base del PWM è praticamente ininfluente. In compenso ho la certezza del completo e sicuro dominio del regolatore.

 

Per non avere ulteriore jitter legato al tempo variabile di esecuzione del regolatore, metto in uscita, all'inizio del regolatore, la correzione della precedente elaborazione; in questo modo introduco un ritardo costante nella correzione che non causa inconvenienti.

 

 

Link al commento
Condividi su altri siti

Sandro Calligaro

Livio, non credo di aver capito bene...

Il fatto di usare un altro timer, che giri ad esempio ad 1/3 della frequenza di PWM, ovviamente permette di non spezzare l'aggiornamento del controllo in più parti (il che causa anche un certo "sfrido").

Riguardo al jitter, in alcune applicazioni non è importante, e comunque (a meno di non legare il campionamento dell'ADC ad un evento sul timer, cosa che non mi pare si possa fare, sull'Atmega328P), rimane, perché la chiamata della funzione di interrupt richiede alcuni passi di durata variabile.

Avere uno sfasamento fisso tra PWM e campionamento, invece, è un problema nel caso della corrente di un induttore, ma stiamo parlando di problemi del secondo ordine...

 

Riguardo a quello che dicevo sopra, cioè che bisogna verificare la durata dell'esecuzione, questo è vero, ovviamente, in ogni caso: bisogna assicurarsi che l'esecuzione non duri "mai" più di un ciclo.

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

Vi ringrazio per i vostri interventi,

sto andando avanti un po per tentativi, non sono esperto, ma sto imparando molte cose grazie anche a voi.

Per ora sono a questo punto:

tutte le prove sono state fatte a 32volt il massimo che puo fornire il mio alimentatore

tutte le masse sono in comune.

ho un pid per il controllo della corrente che funziona piu o meno bene con l'adc che va in free running mode (interrupt quando é disponibile una nuova conversione) e il pid che fa i calcoli nel main loop ogni 200 microsecondi senza interrupt.

ho scritto una sequenza di commutazione rudimentale a 4 step utilizzando i due sensori hall del motore con due interrupt uno per ogni sensore.

In questo modo appena do tensione al bus dell IPM il motore inizia a girare, dal rumore che fa sembra che ogni tanto perda qualche commutazione (rumore tipo motore a scoppio scarburato), non capisco perché ma fa niente.

Vorrei provare ora questa configurazione attaccando il circuito alla rete. A parte gli optoisolatori per isolare arduino e verniciare lo stampato per evitare scintille dove c'é alta tensione avete altri consigli da darmi? Sul circuito ho messo un fusibile da 2.5 A.

La mia paura é che il pid funzioni a 30V, ma poi quando il tutto é alimentato a 220 (310vcc) non riesca a controllare la corrente o sia instabile

 

Link al commento
Condividi su altri siti

Sandro Calligaro
8 ore fa, marcoc4d scrisse:

La mia paura é che il pid funzioni a 30V, ma poi quando il tutto é alimentato a 220 (310vcc) non riesca a controllare la corrente o sia instabile

Il guadagno equivalente dell'inverter viene aumentato di circa 10 volte (310V /30V), quindi, dal punto di vista della dinamica, per avere lo stesso comportamento dovresti dividere per 10 entrambi i guadagni del PID.

Un problema che potrebbe sorgere è che il rumore sulla misura di corrente aumenti, di molto.

 

8 ore fa, marcoc4d scrisse:

ho un pid per il controllo della corrente che funziona piu o meno bene con l'adc che va in free running mode (interrupt quando é disponibile una nuova conversione) e il pid che fa i calcoli nel main loop ogni 200 microsecondi senza interrupt.

Non ho capito quale corrente misuri e controlli. Ci sono 3 correnti, in totale.. 🙂

Mandare l'ADC in free-running non è una buona scelta, sarebbe meglio legare l'aggiornamento del regolatore ad una precisa lettura dell'ADC. In ogni caso, penso che non sia il problema principale.

Fai attenzione alla priorità degli interrupt.

 

8 ore fa, marcoc4d scrisse:

ho scritto una sequenza di commutazione rudimentale a 4 step utilizzando i due sensori hall del motore con due interrupt uno per ogni sensore.

Se ho capito bene, ogni variazione delle uscite delle sonde di Hall corrisponde a 90° elettrici.

Quindi non si deve commutare, e non ha senso fare 4 step, perché il motore è comunque trifase.

Si dovrebbero quindi ricavare posizione e velocità dalle sonde, per poi commutare ogni 60° (BLDC).

 

La posizione va in pratica incrementata di 90° ad ogni fronte di salita o discesa delle sonde Hall (se supponi che la rotazione sia sempre nello stesso verso), la velocità si può stimare come 90°/tempo tra due fronti delle sonde. La velocità serve per aggiornare la stima di posizione tra una commutazione e l'altra delle sonde.

 

Sto immaginando un modo semplice per implementare la commutazione, con numeri interi, e mi viene in mente questo:

 

#define MOLTIPLICATORE    (1<<10)
#define DEG90             (90*MOLTIPLICATORE)

...

if (stato_Hall != stato_Hall_prec)          // rileva l'occorrenza di una commutazione delle sonde
{
  pos_Hall += DEG90;                        // aggiorna la posizione data dalle sonde
  if (pos_Hall>DEG360)
    pos_Hall -= DEG360;                     // normalizza l'angolo sul giro (evita overflow)
    
  vel = DEG90/tempo_Hall;                   // calcola la velocità in gradi*MOLTIPLICATORE / periodi di controllo
  tempo_Hall = 0;                           // azzera il contatore dei periodi (tempo) trascorsi dall'ultima commutazione
}
else
  tempo_Hall++;                             // aggiorna il conteggio dei periodi (tempo) trascorsi dall'ultima commutazione

 

pos = pos_Hall + vel*tempo_Hall;            // stima la posizione tra due fronti delle sonde, supponendo costante la velocità

 

// COMMUTAZIONE in base a pos, considerando step di DEG60 unità

 

 

Funzionerà male per velocità molto alte...

 

 

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

il 8/10/2019 at 18:02 , Sandro Calligaro scrisse:

Riguardo al jitter, in alcune applicazioni non è importante, e comunque (a meno di non legare il campionamento dell'ADC ad un evento sul timer, cosa che non mi pare si possa fare, sull'Atmega328P), rimane, perché la chiamata della funzione di interrupt richiede alcuni passi di durata variabile

 

La campionatura dell'ADC la puoi legare tranquillamente ad un evento di interrupt sul timer, rimane il problema della durata della conversione, della sua costanza (come durata) che, con questo processore, non è trascubile, rispetto alla freqeunza di PWM.

La funzione di interrupt richiede solo una chiamata alla routine di servizio, mentre a liviello di operazione macchina c'è il salvataggio dei registri, però tutto questo è descritto e ben quantificato dalla documentazione del processore, comunque son pochi cicli di clock e, soprattutto, è un tempo rigorosamente costante.

Link al commento
Condividi su altri siti

12 ore fa, Sandro Calligaro scrisse:

Il guadagno equivalente dell'inverter viene aumentato di circa 10 volte (310V /30V), quindi, dal punto di vista della dinamica, per avere lo stesso comportamento dovresti dividere per 10 entrambi i guadagni del PID.

immaginavo ci fosse questa relazione ma non ero certo

12 ore fa, Sandro Calligaro scrisse:

Non ho capito quale corrente misuri e controlli. Ci sono 3 correnti, in totale..

quella del bus, il ritorno comune verso massa delle tre fasi come nello schema che avevo postato

 

12 ore fa, Sandro Calligaro scrisse:

Se ho capito bene, ogni variazione delle uscite delle sonde di Hall corrisponde a 90° elettrici.

Quindi non si deve commutare, e non ha senso fare 4 step, perché il motore è comunque trifase.

Si dovrebbero quindi ricavare posizione e velocità dalle sonde, per poi commutare ogni 60° (BLDC).

Si infatti, quindi ogni 90° elettrici commuto e sposto di 90° il flusso così con due interrupt semplici e senza fare calcoli faccio girare il motore. Non é certo una soluzione ottimale ma

considerando che il pid per il controllo della corrente consuma circa il 50% della cpu e che manca ancora il loop di controllo della velocità, non é che si possa fare molto.

Mi sembra di capire che (come mi avevate già detto) con arduino non si riesca a scrivere una soluzione ben fatta per controllare il motore. Potrei provare ad eliminare il loop di corrente e tenere solo quello di velocità.

A questo punto quello che mi interessa di più é arrivare a testare la parte di potenza con la tensione di rete per vedere se funziona e poi passare ad una scheda più potente tipo fishino come diceva Livio.

12 ore fa, Sandro Calligaro scrisse:

if (stato_Hall != stato_Hall_prec)          // rileva l'occorrenza di una commutazione delle sonde
{
  pos_Hall += DEG90;                        // aggiorna la posizione data dalle sonde
  if (pos_Hall>DEG360)
    pos_Hall -= DEG360;                     // normalizza l'angolo sul giro (evita overflow)
    
  vel = DEG90/tempo_Hall;                   // calcola la velocità in gradi*MOLTIPLICATORE / periodi di controllo
  tempo_Hall = 0;                           // azzera il contatore dei periodi (tempo) trascorsi dall'ultima commutazione
}
else
  tempo_Hall++;                             // aggiorna il conteggio dei periodi (tempo) trascorsi dall'ultima commutazione

 

pos = pos_Hall + vel*tempo_Hall;            // stima la posizione tra due fronti delle sonde, supponendo costante la velocità

 

// COMMUTAZIONE in base a pos, considerando step di DEG60 unità

Se non ho capito male questo codice deve stare dentro la ISR di un timer?

Link al commento
Condividi su altri siti

Sandro Calligaro
Il 12/10/2019 alle 11:34 , marcoc4d ha scritto:

Se non ho capito male questo codice deve stare dentro la ISR di un timer?

Sì.

Link al commento
Condividi su altri siti

Sandro

ho provato la commutazione a sei step con un codice simile a quello che hai postato tu, io ho usato il registro ocr per generare l'interrupt al momento desiderato per la commutazione, ma sostanzialmente é la stessa cosa.

Funziona perfettamente. Il rumore non é trascurabile però.

Ho misurato la velocità del motore con applicati 50V e va a 96 giri/min. Facendo una veloce proporzione a 300 V dovrebbe andare 600 giri/min.

Non capisco come faccia la centrifuga ad andare a 1400 giri/min, dovrebbe essere alimentato a più di 600 volt? Vuol dire che c'é qualcosa per alzare la tensione a 600 Volt?

P.S. temo che l'ipm si sia rotto una fase é in corto. A sto punto penso di rifare il circuito usando un driver trifase e 6 igbt.

Link al commento
Condividi su altri siti

11 ore fa, marcoc4d ha scritto:

Facendo una veloce proporzione a 300 V dovrebbe andare 600 giri/min.

 

Non hai i dati di questo motore?

Mi sembrano valori non normali per un BLDC da lavatrice, anche se fosse un motore da trazione diretta.

Link al commento
Condividi su altri siti

Livio,

purtroppo non ho trovato da nessuna parte i dati di questo motore, spulciando su internet ho trovato sul sito della fisher paykel delle specifiche di motori simili per lavatrice

https://www.fisherpaykeltechnologies.com/wp-content/uploads/MB45T-direct-drive-motor.pdf

 

MOTOR FUNDAMENTALS

K e  - BEMF constant 3.11 V/rad.s-1 Line to neutral, RMS Voltage

Kt – Torque constant 9.33 Nm/A

Km - Motor constant 2.40 Nm / Watt Inductance 62.82 mH Line to neutral inductance (includes self and mutual inductance)

INDICATIVE PERFORMANCE * / ** AT NOMINAL 230VRMS

Speed – maximum 1,400 rpm *

Torque at 50 rpm 45 Nm *

Torque at 1,400 rpm 4.5 Nm *

Power output – at 50 rpm 240 W * at 45 Nm torque

Power output – at 1,400 rpm 660 W * at 4.5 Nm torque

Efficiency at 1,400 rpm 79% * at 4.5 Nm torque

 

Come va interpretata la K e? "Line to neutral" vuol dire da una fase al comune delle tre fasi?

Modificato: da marcoc4d
Link al commento
Condividi su altri siti

Sandro Calligaro

I due articoli che avevo elencato all'inizio fanno sicuramente riferimento al motore LG, anche se ce ne potrebbero essere diverse varianti.

In particolare, uno dice che il lavoro è stato supportato da LG, sull'altro ho recentemente assistito ad una presentazione, in cui un autore menzionava LG.

 

A. Yoo, S. K. Sul, D. C. Lee and C. S. Jun, "Novel Speed and Rotor Position Estimation Strategy Using a Dual Observer for Low-Resolution Position Sensors," in IEEE Transactions on Power Electronics, vol. 24, no. 12, pp. 2897-2906, Dec. 2009.

Pole / slot: 48 / 36

Rated torque: 25 Nm

Base speed: 600 rpm

Rated current: 3 A

Magnet flux-linkage: 0.0926 Vs

Stator resistance: 4.5 Ohm

Stator inductance: 26 mH

 

H. J. Ahn and D. M. Lee, "A New Bumpless Rotor-Flux Position Estimation Scheme for Vector-Controlled Washing Machine," in IEEE Transactions on Industrial Informatics, vol. 12, no. 2, pp. 466-473, April 2016.

 

Rated power: 1000 W

Rated speed: 1000 rpm

Rated current: 10 A

Number of poles: 48

Stator resistance: 5.0 Ohm

Stator inductance: 35 mH

Flux linkage: 0.2 Vs

 

Purtroppo, i due articoli riportano valori abbastanza diversi, li si potrebbe almeno confrontare con quelli che ha postato marcoc4, ma ci vuole un attimo di tempo (nei dati di marcoc4d, peraltro, non c'è la corrente nominale, e non riesco ad interpretare la Km).

Una cosa che salta all'occhio, a dire il vero, è il diverso numero di cave e poli tra i motori dell'articolo e quello di Marco.

 

E' certo che a 1400 rpm ci arrivano in deflussaggio.

 

Link al commento
Condividi su altri siti

L'unico dato che ho di quel motore é 24 poli che si trova sul service manual, ma non so che affidabilità abbia.

Sandro sul link che ho messo prima c'é un grafico della pull down curve, magari dalla coppia massima del grafico si puo ricavare la corrente nominale sapendo la Kt.

 

Immaginavo ci fosse un trucco per far andare piu veloce il motore :)

Link al commento
Condividi su altri siti

Si il motore della lavatrice LG,

sono andato a rileggere il service manual, dice:

"The DD motor can be driven from stopped to maximum speed in infinite steps in either direction. There are 36 poles on the stator; 12 permanent magnets spaced around the rotor. There are no brushes to wear out. Unlike a more traditional brushless motor, the rotor surrounds the stator rather than being attached to it."

Non é chiaro, provo ad attaccare due fasi all'alimentatore e contare quanti scatti fa per fare un giro girando il cestello a mano.

Link al commento
Condividi su altri siti

Sandro Calligaro

L'altra cosa che puoi fare è contare i periodi della back-EMF, girando a mano e registrando la tensione a vuoto con un oscilloscopio. 

Link al commento
Condividi su altri siti

Poiché devo sostituire l'ipm rotto e arduino é alquanto risicato come prestazioni, sto pensando di orientarmi su una soluzione della ST: controller serie nucleo e scheda di valutazione ipm già fatta e pensata per interfacciarsi coi loro controller. In più c'é tutta una serie di librerie framework etc etc per il controllo di motori pmsm con foc, 6 step commutation, defluxing, insomma c'é di tutto. L'unica cosa é che la scheda di potenza non é isolata dal controller. Mi chiedo se può bastare collegare il controller al pc tramite un isolatore usb?

Link al commento
Condividi su altri siti

Sandro Calligaro

Stavo per proporti qualcosa del genere...

 

Riguardo all'isolamento, molto dipende dall'alimentazione. Se usi un alimentatore, non ci sono grossi problemi.

Se usi la rete raddrizzata, il problema principale è che non puoi fare misure sulla parte di controllo, a meno di non usare una sonda differenziale, ed anche in quel caso occorre molta attenzione. In pratica, non potresti toccare né la parte di potenza, né quella di controllo.

 

Uno stadio di isolamento verso il PC è comunque sempre bene averlo, anche se non ci sono in ballo tensioni alte.

L'isolatore USB può andare bene. Considera però che di norma, negli azionamenti, è obbligatorio avere isolamento doppio o singolo rinforzato tra la potenza e le parti di comunicazione. Un singolo isolamento ha comunque una certa probabilità di rompersi (anche se abbastanza remota, infatti nei kit di sviluppo isolano a livello dell'USB, solitamente (per risparmiare).

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

Mentre aspetto l'arrivo del nuovo materiale della st, sto studiando l'sdk che forniscono per la FOC e il flux weakening.

Ci sono alcune cose che non capisco, la prima e forse la piu importante é che non riesco a trovare su internet una descrizione generale semplice del flux weakening. Da quel poco che ho capito si é in deflussaggio quando il flusso del rotore é oltre i 90° elettrici rispetto allo statore, é vero?

L'altra cosa l'sdk della st contiene dei parametri non spiegati per il deflussaggio che sono dei parametri per il pid di deflussaggio e il limite di tensione (min 60.5%, max 100%), non ho la minima idea di cosa siano e cosa facciano :)

Modificato: da marcoc4d
Link al commento
Condividi su altri siti

Sandro Calligaro

Deflussaggio (per un motore "brushless" isotropo, come il tuo)

In pratica, il problema è che, se fai lavorare il motore con la sola corrente di asse q (scelta che massimizza il rapporto coppia/corrente), la tensione sale quasi linearmente con la velocità, perché, approssimativamente

V(ampiezza) = velocità x flusso di statore (ampiezza)

L'ampiezza del flusso di statore dipende principalmente da quella del flusso di rotore (quindi del magnete), ed in parte dal flusso induttivo (L x corrente). La tensione causata dal magnete è chiamata tensione indotta (back-EMF). Il flusso del magnete è sull'asse d (quello su cui normalmente si impone corrente nulla).

 

Ci sarà un valore di velocità oltre il quale la tensione necessaria a controllare il motore non è sufficiente. Quella è la velocità base, se si vuole andare oltre quella velocità occorre "deflussare". "Deflussare" significa ridurre l'ampiezza del flusso di statore complessivo, cioè quello dato dal flusso del magnete (asse d) più quello dato dalle correnti (L x I), che è nella stessa direzione delle correnti.

Solitamente, per il tuo tipo di motore, il flusso dato dalle correnti sull'asse q non fa la differenza sull'ampiezza del flusso complessivo, perché la componente maggiore è quella del magnete (positiva sull'asse d).

Per deflussare si va a contrastare il flusso del magnete, imponendo corrente negativa sull'asse d e generando quindi flusso in opposizione a quello del magnete.

In questo modo, all'aumentare della velocità, si riesce a mantenere la tensione costante, ossia entro il limite dell'inverter (o un po' più bassa, per avere un margine).

Il "costo" di questa operazione è che si "spreca" della corrente solo per ridurre la tensione indotta, invece di usarla solo per la produzione di coppia.


Situazione normale

image.png.2ae2184ef6359f9215d6e08ffda95afb.png

 

 

Con Id negativa (deflussaggio)

image.png.11137497aab74f5ddc9833b01122ff8b.png

 

Per capire quanta corrente occorre imporre sull'asse d, ci sono due modi:

- si conoscono i parametri del motore e la tensione che si vuole mantenere, quindi si calcola analiticamente la corrente necessaria ad ottenere quel risultato (istante per istante, in base alle condizioni di lavoro);

- si usa un regolatore che confronta l'ampiezza della tensione in uscita dai regolatori (più il disaccoppiamento degli assi, se c'è) con il valore di tensione obiettivo (un po' sotto il limite dell'inverter), ed in base a questo "errore" genera un valore di corrente di asse d da imporre, cercando di portare la tensione al valore desiderato (in pratica, "indovinando" dinamicamente il valore "giusto" per la corrente di asse d).

Il secondo metodo ha vari vantaggi, primo fra tutti che per farlo funzionare non occorrono troppi calcoli e non serve conoscere con precisione alta i parametri del motore.

Ha anche degli svantaggi, legati principalmente alla stabilità ed alla rapidità della risposta, ma è comunque il metodo più usato.

 

La cosa è un po' complicata, soprattutto se si cerca di non andare a guardare le equazioni...
Sulla dinamica del loop di tensione (cioè quello che decide Id per mantenere l'ampiezza della tensione costante) ho lavorato piuttosto a lungo, anche recentemente abbiamo pubblicato un criterio di dimensionamento dei guadagni in base all'accelerazione massima e per il caso di un calo di tensione in ingresso.

 

 

 

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

Sandro,

grazie mille per la tua spiegazione, finalmente penso di aver capito cos'é il deflussaggio.

Ho chiesto a ST i sorgenti della libreria dell'sdk ed effettivamente guardando nel sorgente succede proprio quello descritto dal tuo secondo metodo, dopo aver calcolato Id e Iq con la foc, corregge il valore Id con con il pi di deflussaggio.

Link al commento
Condividi su altri siti

Ho un dubbio sul deflussaggio,

mi sembra che la libreria della foc quando si da il comando di "stop" al motore semplicemente interrompe la pwm. 

Non c'é il rischio di sovratensione sul bus se il motore sta andando in deflussaggio e si interrompe brutalmente la pwm?

Link al commento
Condividi su altri siti

Sandro Calligaro
2 ore fa, marcoc4d ha scritto:

Non c'é il rischio di sovratensione sul bus se il motore sta andando in deflussaggio e si interrompe brutalmente la pwm?

Certo!

Hai capito bene il problema, vedo. Quella è una delle cose che, dal punto di vista del modello, non è stata ancora ben coperta in letteratura.

Non si trova un calcolo di quale sarà la tensione finale di bus DC nel caso in cui si interrompa la PWM (che può essere anche per un guasto!).

L'unico modo per stare tranquilli è avere delle protezioni (crowbar) o avere tutto sovra-dimensionato come tensione massima (di rottura degli switch e dei condensatori).

Modificato: da Sandro Calligaro
Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora

×
×
  • Crea nuovo/a...