marcoc4d Inserito: 30 giugno 2018 Segnala Share Inserito: 30 giugno 2018 Buongiorno forum, scrivo perché vorrei comandare il motore BLDC di una lavatrice LG. Si tratta di un motore bldc trifase con 36 poli (12 per fase) nello statore e credo 12 o 24 poli nel rotore. Quello che non capisco é che ha solamente 2 sensori Hall. Come fa la scheda della lavatrice a comandare questo motore? L'unica possibilità che riesco ad immaginare é tramite una commutazione a tre step invece di 6. Secondo voi é possibile? Esistono altri modi di commutare un motore bldc trifase con solo due sensori hall? Grazie Marco Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 1 luglio 2018 Segnala Share Inserita: 1 luglio 2018 Il motore in questione non lo chiamerei "brushless DC", secondo me quel motore ha tensioni indotte ("back-EMF") sinusoidali (non trapezoidali). Se è quello che ho visto, ha due "particolarità": rotore esterno ed avvolgimento sul dente. La back-EMF è relativamente facile da misurare: basta qualcosa per far girare il motore (volendo anche a mano) ed un oscilloscopio (misurando la tensione concatenata, ad esempio). Dal punto di vista del controllo, però, credo venga pilotato in controllo vettoriale. Il controllo vettoriale, rispetto al controllo "BLDC", è più "regolare", avendo correnti sinusoidali. Questa cosa è importante per una lavatrice, visto che la rumorosità conta molto. Per fare controllo vettoriale, se si usano sensori di Hall digitali (ON/OFF), occorre ovviamente interpolare. Ci sono tecniche anche abbastanza sofisticate per farlo, ma in definitiva il problema rimane a bassa velocità, dove l'informazione arriva con un tempo di campionamento equivalente piuttosto lungo. In ogni caso, con due sensori di Hall digitali si può dividere l'angolo in 4 invece che in 6 parti, per poi interpolare opportunamente, ma potrebbe anche essere che quei sensori siano letti in analogico, andando quindi a sfruttare la loro linearità (o quasi linearità) e quindi utilizzandoli come sensori seno-coseno. Sarei curioso di sapere come sono disposti (e magari qual è il circuito di condizionamento), se potessi mandarci qualche foto in proposito, sarebbe interessante. Suppongo che la tensione nominale di quel motore sia vicina alla tensione di rete monofase raddrizzata. Per quanto riguarda la possibilità di controllare quel motore, credo che l'opzione più semplice sia quella di procurarsi un drive industriale (alimentato a 230V o 400 V) con controllo sensorless per PMSM. Se l'applicazione prevede solo controllo di velocità e non interessa di andare a bassissima velocità o spingere da fermo, allora un buon controllo sensorless dovrebbe funzionare. Ci sono moltissimi costruttori, ormai, che nei loro prodotti di punta offrono questa funzionalità. Mi sentirei abbastanza sicuro di consigliarti, ad esempio, un ADV200 Gefran, visto che lo conosco bene e l'ho provato anche con motori simili (avvolgimento sul dente e rotore esterno). Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 1 luglio 2018 Autore Segnala Share Inserita: 1 luglio 2018 Ciao Sandro, innanzi tutto grazie per la tua risposta. Sono partito con l'idea che fosse un BLDC perché sul service manual dice che si tratta di un "Brushless DC motor". Sempre sul service manual parla dei due hall sensor che restituiscono 0 o 5V quindi valori binari. Allego due foto prese da internet del motore in questione e dei sensori hall. La tensione di funzionamento é quella di rete monofase raddrizzata. Mi resta il dubbio nel caso si trattasse effettivamente di un BLDC se si puo fare una commutazione a 3 step invece di 6 visto che ci sono solo due sensori Hall. A me serve farlo funzionare a bassa e alta velocità come in una lavatrice. Dal rumore che fa quando va la lavatrice mi sentirei di dire che é commutato come un BLDC e non con correnti sinusoidali nel senso che fa proprio rumore di ingranaggio. Pero non sono un esperto e potrei dire un sacco di cose errate. grazie Marco Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 1 luglio 2018 Segnala Share Inserita: 1 luglio 2018 Sui nomi c'è parecchia confusione nell'industria, figuriamoci quando si rivolgono a riparatori o ai clienti. In ogni caso non escludo che lo pilotino come BLDC. Ho anch'io una LG direct-drive, e quel rumore l'avevo interpretato più come dovuto alla coppia di cogging (coppia a corrente nulla) o comunque alle oscillazioni della coppia nel periodo elettrico. In motori con avvolgimento sul dente, infatti, spesso le oscillazioni di coppia sono abbastanza pensanti, e a velocità bassa queste si sentono di più a causa della risposta meccanica, che tende ad essere passa-basso (salvo qualche risonanza). Non sono un esperto di progettazione di macchine, ma mi pare che una configurazione come questa sia particolarmente problematica in termini di oscillazioni di coppia e di cogging. Il pilotaggio BLDC può essere visto come un'approssimazione di quello sinusoidale, e nel caso trifase non si scappa, ci vogliono 6 diversi stati. Con 2 sonde si potrebbero ottenere 4 stati, ma a seconda di come sono disposti si può pensare di avere una risoluzione di 1/4 di giro elettrico oppure di avere alcune parti del periodo "morte". Se ci fossero state 3 sonde avrei detto che il pilotaggio BLDC era molto probabile, con 2 ritengo che lo sforzo nell'interpolazione e compensazione non valga la pena (meglio il vettoriale, a quel punto). Potrebbe essere che usino quelle sonde come punto di partenza, per poi andare in sensorless appena la velocità è un po' più alta, potendo comunque sfruttare le sonde come informazione certa (si possono mischiare le due sorgenti di informazione, ovviamente). In fin dei conti, una risoluzione di 90° dovrebbe essere il minimo per non far ruotare accidentalmente il rotore in senso inverso, all'avvio. Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 6 luglio 2018 Segnala Share Inserita: 6 luglio 2018 Aggiungo (perché, parlandone con dei colleghi, uno di loro me l'ha segnalato), che la gestione di uno motore del genere con 2 sensori di Hall è trattata in qualche articolo scientifico, ad esempio ho trovato questi, che sembrano trattare proprio il caso del motore 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. 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. Se non hai accesso ad un account IEEExplore, potresti provare a richiedere una copia agli autori su Researchgate. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 24 ottobre 2018 Autore Segnala Share Inserita: 24 ottobre 2018 Ciao Sandro, mi scuso per il lungo silenzio, volevo solo dirti che ho controllato con l'oscilloscopio ed hai ragione, la BEMF é sinusoidale. Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 24 ottobre 2018 Segnala Share Inserita: 24 ottobre 2018 La questione della classificazione è, come accennavo, più una convenzione che altro. Comunque, potrebbe benissimo essere che lo controllino come BLDC. Con cosa vorresti farlo funzionare, con un drive commerciale? Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 24 ottobre 2018 Autore Segnala Share Inserita: 24 ottobre 2018 Vorrei farlo andare con arduino e STK554U362A Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 24 ottobre 2018 Segnala Share Inserita: 24 ottobre 2018 Il progetto di un inverter a tensione alta (300-400 V) è difficile, se non hai già esperienza di progettazione di qualcosa del genere ti sconsiglio di cominciare da questo caso... Il debugging è tra l'altro anche piuttosto pericoloso, soprattutto se non usi isolatori per la parte di controllo. Se poi vuoi farlo funzionare a bassa velocità, ti accorgerai che quella è la condizione più critica per il controllo. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 24 ottobre 2018 Segnala Share Inserita: 24 ottobre 2018 1 ora fa, marcoc4d scrisse: con arduino Ho dei dubbi che, dato che la robustezza EMC di arduino è praticamente nulla, possa funzionare dato che un'inverter genera fortissimi disturbi. Poi ci sono le giustissime osservazioni di Sandro Calligaro. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 24 ottobre 2018 Autore Segnala Share Inserita: 24 ottobre 2018 Grazie Sandro e Livio per la messa in guardia, so perfettamente di avventurarmi in un campo pericoloso, ma sono molto curioso. Non ho intenzione di collegare la parte logica dell STK554U362A direttamente ad arduino, terrei alimentazioni separate e accoppiamento ottico tra i due, e poi non andrei ad alimentare con la tensione di rete raddrizzata la parte di potenza. Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 24 ottobre 2018 Segnala Share Inserita: 24 ottobre 2018 L'inverter irradia e arduinio è molto sensibile sia ai disturbi condotti che a quelli irradiati. Poi c'è anche il problema della frequenza di base o carrier frequency (frequenza portante) dei segnali modulati in PWM; non so quale è lagamma di frequenza che si usa nei moderni dispositivi, ma mi sembra molto più elevata di quella del PWM di arduino che, tra l'altro, ha una risoluzione molto povera: solo 1:255. Sandro Calligaro sicuramente potrà dare notizie più precise in ordine a questi dati Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 24 ottobre 2018 Autore Segnala Share Inserita: 24 ottobre 2018 Arduino mega con atmega2560 ha anche il PWM a 32 bit. Considerando che ha un clock a 16 megahertz non penso che dovrebbero esserci problemi di velocita, pero le mie sono considerazioni spannometriche. Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 28 ottobre 2018 Segnala Share Inserita: 28 ottobre 2018 La PWM non è il problema principale, anche con Arduino Uno si riesce a far funzionare la PWM a frequenza alta. Occorre ovviamente andare a modificare direttamente i registri di configurazione, come si farebbe con qualunque altro microcontrollore senza usare librerie "driver". La risoluzione non è alta, ma non è nemmeno questo il problema fondamentale: a 10 kHz (frequenza tipica per controllo motore, per potenze di qualche kW), contando a 16 MHz con rampa triangolare (per fare il campionamento in mezzo) si ha una risoluzione di 1/800, se il contatore lo si fa andare con rampa singola (dente di sega) si ha 1/1600, che tutto sommato potrebbe essere accettabile. Sono certo dei numeri che indico, perché l'ho fatto per uso didattico. Dal punto di vista dei conti, l'Atmega328p è "scarso", non permette di fare più di qualche conto in virgola fissa, per ogni periodo. Il Mega non lo conosco. Un altro problema (abbastanza grosso) che si ha usando l'ambiente Arduino è la mancanza di strumenti di debugging. Detto questo, se si tratta di fare un controllo molto semplice, tipo BLDC, può darsi che anche Arduino Uno sia sufficiente. Anche io, come Livio, mi aspetto che l'immunità di un Arduino sia problematica. Non ho mai analizzato la cosa, ma il routing sembra pensato solo per ottenere una certa disposizione dei connettori, non per garantire percorsi adatti al segnale. Non so nemmeno se ci sia un piano di massa... Se dovessi iniziare io, proverei prima con un motore a bassa tensione, col quale si può giocare con un po' di tranquillità. Per passare a tensione più alta, una possibilità potrebbe anche essere quella di utilizzare la scheda di potenza di un vecchio inverter commerciale. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 5 ottobre 2019 Autore Segnala Share Inserita: 5 ottobre 2019 Rieccomi qua dopo quasi un anno, purtroppo mi sto dedicando a questo progetto per hobby e non ho molto tempo da dedicarci. Vi aggiorno: Ho fatto un circuito stampato con l'IPM STK554U3. Per il momento ho alimentato il circuito con 30 Volt provenienti da un alimentatore stabilizzato, collegato come carico su solo due delle tre fasi di uscita un ferro da stiro e una stufetta da 2000W in parallelo. Lo scopo era di provare il PWM ed l'ADC di arduino per vedere se fosse possibile utilizzare una libreria di un PID come loop di controllo della corrente. Come sensore di corrente utilizzo un ACS712 da 20 A con l'uscita collegata ad input analogico di arduino. Con la pwm (17khz) al 50% il carico assorbe 1.01 A e l'adc di arduino da 490 come valore letto. Ho provato a dare 490 come set point al PID ma non c'é modo di regolare i parametri per ottenere una risposta sufficientemente stabile precisa e veloce. Penso che il problema sia che la risoluzione di 1024 del ADC di sia troppo bassa per poter funzionare. La mia domanda é: non si puo' evitare o integrare il current loop conoscendo velocita del motore, frequenza della pwm, resistenza e induttanza degli avvolgimenti del motore? Grazie mille a chi vorrà rispondere Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 5 ottobre 2019 Segnala Share Inserita: 5 ottobre 2019 3 ore fa, marcoc4d scrisse: Ho provato a dare 490 come set point al PID ma non c'é modo di regolare i parametri per ottenere una risposta sufficientemente stabile precisa e veloce. Cosa controlli con il PID. Perchènon fai uno schemino a blocchi del regolatore con le variabili di ingresso e uscita. Poi con quale periodo riaggiorni il PID. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 5 ottobre 2019 Autore Segnala Share Inserita: 5 ottobre 2019 Grazie mille Livio per la risposta, Ti allego uno schemino fatto a mano su cui ho riportato i parametri del PID In ingresso leggo tramite l'adc di arduino la tensione di uscita del sensore di corrente messo in serie al carico. é un sensore a effetto hall che quando la corrente é zero da 2.5V, con una variazione di 100mv per Ampere in piu o in meno a seconda della direzione della corrente. Non sono sicuro che il periodo di aggiornamento del pid sia effettivamente di 10 ms anche se é il tempo che ho impostato nella configurazione. Provero a verificare l'effettivo intervallo di aggiornamento. La pwm é impostata con risoluzione di 900 e frequenza a 17khz. Con kp=ki=1 e kd=0 funziona ma é lentissimo, alri valori lo fanno oscillare. Il carico sono un ferro da stiro da 2000w e una stufa da 2000w in parallelo. Ho anche messo un filtro RC (r 10k e C 220 uF)sull uscita del sensore di corrente per limare i picchi della pwm. Mi rendo conto che tutto cio é molto empirico e non mi meraviglia che non funzioni. Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 5 ottobre 2019 Segnala Share Inserita: 5 ottobre 2019 (modificato) Suppongo (non sono andato a guardare il datasheet) che l'ingresso "HIN1" del modulo sia il pilotaggio dello switch alto della fase U, mentre "LIN3" sia quello basso della fase W. Il principale problema nel tuo caso, mi sembra di poter dire, è il periodo di aggiornamento. Con carichi molto più "induttivi" (induttanze almeno attorno ad 1 mH), e tensioni di bus DC attorno a 500 V, la frequenza di aggiornamento è solitamente 10 kHz, cioè 2 ordini di grandezza superiore rispetto al tuo caso. Anche se la tua tensione di bus è 10-20 volte più bassa, hai probabilmente un'induttanza molto bassa. Se provi a visualizzare l'uscita del sensore di corrente, avrai probabilmente un'onda quasi quadra. Supponendo anche 1 mH di induttanza (che mi sembra molto sovra-stimata, per i carichi che hai adesso), se dovessi applicare piena tensione (30 V), all'inizio la corrente salirebbe a 30 kA/s, che in 10 ms corrisponde a 300 A. Ovviamente, la resistenza del carico (e forse anche quella equivalente dell'alimentatore) limita la corrente, ma le variazioni in un periodo di controllo sono molto ampie. Inoltre, per come è collegato il carico, non hai la possibilità di forzare tensione negativa sul carico, quindi la tensione può scendere solo per la caduta resistiva del carico. In pratica, il tuo controllore vede un oggetto che fa salire la corrente molto velocemente, ma la fa scendere lentamente (specie quando si avvicina a zero). Per poter avere un po' di più "libertà di azione" dovresti modulare anche la seconda gamba (in pratica, usando un ponte intero o ponte ad H). Un altro problema potrebbe essere il windup della parte integrale del regolatore. Assicurati di applicare almeno una limitazione della parte integrale che la mantenga nel range 0-900 (cioè quello del valore di compare della PWM). Il guadagno derivativo fai bene a lasciarlo nullo, per un carico del primo ordine (L-R). PS: usare un solo sensore di corrente rende le cose molto complicate, in vista del controllo del motore. Ciò non toglie che si possa fare, ma non so quanto sia fattibile con Arduino. Quale strategia di controllo vorresti applicare sul motore, alla fine? Hai qualche buon riferimento (libro, application note, ...)? 5 ore fa, marcoc4d scrisse: non si puo' evitare o integrare il current loop conoscendo velocita del motore, frequenza della pwm, resistenza e induttanza degli avvolgimenti del motore? Costruire un modello che stimi la corrente a partire dalle altre grandezze è possibile, ma è molto complicato e poco preciso, quindi non si avrebbe la certezza del valore effettivo di corrente. Va tenuto presente che la corrente è legata direttamente alla coppia... L'alternativa sarebbe quella di infischiarsene della corrente, imponendo l'ampiezza della tensione in funzione della velocità ed applicandola ad una delle fasi, in funzione della posizione (controllo brushless DC). E' più o meno quello che fanno alcuni controllori da pochi $, utilizzati in modellini o droni. La corrente, però, va comunque tenuta sotto osservazione per protezione. Modificato: 5 ottobre 2019 da Sandro Calligaro Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 6 ottobre 2019 Segnala Share Inserita: 6 ottobre 2019 13 ore fa, marcoc4d scrisse: Non sono sicuro che il periodo di aggiornamento del pid sia effettivamente di 10 ms anche se é il tempo che ho impostato nella configurazione Come non sei sicuro? Non solo devi esserne certo maquesto tempo deve essere molto costante, se varia si traduce in Jitter che accresce l'instabilità del regolatore. Il periodo di richiamo del regolatore deve essere generato dall'interrupt di un timer, il tutto deve avere priorità massima. Poi, come ha già scritto Sandro Calligaro, 10 ms sono un'eternità per una siffatta regolazione, un tepo corretto dovrebbe essere dell'ordine dei 100µs o, al massimo, 500µs (anche se avrei dei dubbi in proposito). Questo significa che il tuo micro deve risolvere tutto il PI(D) in meno di 100µs (500µs) per poter dedicare tempo di CPU alle altre operazioni. Sinceramente un arduino 1 non è in grado di farlo, devi spostarti su un qualche cosa con micro a 32 bits e clock più elevato. So che ci sono alcune schede che rientrano nella linea di arduino, che hanno un micro a 32 bits. Ora che Microchip ha assorbito Atmel credo che ci sia anche qualche cosa con micro PIC a 32 bits. Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 6 ottobre 2019 Segnala Share Inserita: 6 ottobre 2019 (modificato) Concordo con Livio. Per provare anche solo a far girare un motore, avere sotto mano l'oscilloscopio direi che è indispensabile. Se ne hai uno, verificare la frequenza di aggiornamento è semplice: basta alzare ed abbassare un pin ogni volta che si esegue l'aggiornamento del controllo. In ogni caso, l'aggiornamento deve essere fatto in un interrupt legato alla PWM. Forse 200 µs sono ancora accettabili, ma solo se l'induttanza non è troppo bassa. La stufa in parallelo al ferro da stiro non mi sembra un carico adatto per le prime prove, perché non usi direttamente il motore (ad es. solo due fasi)? Per didattica, ho usato Arduino Uno e posso dirti che in 50 µs si riesce a leggere una variabile (senza ottimizzare la lettura dell'ADC), applicarle un filtro passa-alto del primo ordine (implementato in virgola fissa con numeri a 16 bit), scalare per un fattore moltiplicativo ed aggiornare la PWM. La lettura dell'ADC richiede circa 20 µs (vado a memoria). Ne deduco che in 200 µs qualcosa si potrebbe riuscire a fare (un controllo BLDC semplice, probabilmente), standoci molto attenti, visto che come carico computazionale un PI non dovrebbe essere molto diverso da un passa-alto del primo ordine... La gestione della virgola fissa è un po' complicata, forse con un esempio si può capire meglio. Potresti postare il codice o un link al PID che usi, tanto per iniziare... Modificato: 6 ottobre 2019 da Sandro Calligaro Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 6 ottobre 2019 Segnala Share Inserita: 6 ottobre 2019 1 ora fa, Sandro Calligaro scrisse: carico computazionale un PI non dovrebbe essere molto diverso da un passa-alto del primo ordine Si tratta di una moltiplicazione in virgola fissa opportunamente scalata, anche se sarebbe meglio usare il real. Idem per l'integrale, in cui oltre alla moltiplicazione per il coefficiente è necessaria la somma, poi è necessaria la somma dei due coefficienti la riscalatura. Ovviamente senza considerare un eventuale coefficiente derivativo o di anticipo di reazione. Facendo tutto in real, con un arduino 1 rev. 3, il solo PI, misurato dalla chiamata al ritorno, impiega qualche cosa che assomiglia molto al millisecondo. Usare una scheda tipo fishino, ad esempio, ti da la potenza di calcolo di un 32 bits, con costi < 50€ ed ambiente di lavoro del tutto uguale ad arduino,oltre ad avere altri miglioramenti. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 6 ottobre 2019 Autore Segnala Share Inserita: 6 ottobre 2019 Grazie alle vostre risposte ho capito che in effetti era normale che il pid fosse lento oppure instabile con parametri alti per cercare di farlo convergere più velocemente. In effetti la frequenza massima teorica di aggiornamento dell'adc di arduino é compresa tra 76923 hz (13µs) e 9615 hz (104µs) a seconda del prescaler che si decide di usare. Leggo il valore dell'adc con l'interrupt senza usare analogread che é lentissima. Quindi forse si riesce a fare un pid funzionante. I 10 ms sono quelli che ho impostato io come frequenza di aggiornamento della libreria del pid dato che di default é impostata a 200ms e l'autore dice che che 200ms é sufficiente per molte applicazioni. Non essendo esperto di questo dominio pensavo che 10 ms fossero sufficienti anche se poi sul campo mi sono reso conto che la regolazione era lentissima. Nel frattempo stamattina ho provato a collegare il motore al circuito ad anello aperto per vedere se la sequenza di commutazione a 6 step funziona. Funziona ma é rumorosissimo, Quindi forse bisogna passare a un comando sinusoidale deducendo la posizione del rotore dai due soli sensori hall in quadratura di cui é dotato il motore. Icollo qui il codice del PID che uso: /********************************************************************************************** * Arduino PID Library - Version 1.1.1 * by Brett Beauregard <br3ttb@gmail.com> brettbeauregard.com * * This Library is licensed under a GPLv3 License **********************************************************************************************/ /* Compute() ********************************************************************** * This, as they say, is where the magic happens. this function should be called * every time "void loop()" executes. the function will decide for itself whether a new * pid Output needs to be computed. returns true when the output is computed, * false when nothing has been done. **********************************************************************************/ bool PID::Compute() { if(!inAuto) return false; unsigned long now = millis(); unsigned long timeChange = (now - lastTime); if(timeChange>=SampleTime) { /*Compute all the working error variables*/ double input = *myInput; double error = *mySetpoint - input; double dInput = (input - lastInput); outputSum+= (ki * error); /*Add Proportional on Measurement, if P_ON_M is specified*/ if(!pOnE) outputSum-= kp * dInput; if(outputSum > outMax) outputSum= outMax; else if(outputSum < outMin) outputSum= outMin; /*Add Proportional on Error, if P_ON_E is specified*/ double output; if(pOnE) output = kp * error; else output = 0; /*Compute Rest of PID Output*/ output += outputSum - kd * dInput; if(output > outMax) output = outMax; else if(output < outMin) output = outMin; *myOutput = output; /*Remember some variables for next time*/ lastInput = input; lastTime = now; return true; } else return false; } Link al commento Condividi su altri siti More sharing options...
Sandro Calligaro Inserita: 6 ottobre 2019 Segnala Share Inserita: 6 ottobre 2019 (modificato) L'aggiornamento dell'azione di controllo, per avere una cadenza precisa, deve essere eseguito nella funzione di interrupt. Se si vuole/deve avere la frequenza di PWM più alta della frequenza di aggiornamento del controllo, si possono "spezzare" su più periodi le operazioni da eseguire. Per fare un esempio con PWM a 10 kHz ed aggiornamento a 5 kHz: alla prima occorrenza dell'interrupt si esegue l'acquisizione, il calcolo dell'errore e della parte proporzionale, al secondo ciclo si calcola la parte integrale e si applica la PWM, per poi ricominciare (qui sotto un esempio). #define FIRST 0 #define SECOND 1 ... void interrupt() { if (state == FIRST) { PI_feedback = ADC_acquisition(); PIreg_err = PI_setpoint - PI_feedback; PIreg_prop = Kp * PIreg_err; state = SECOND; } if (state == SECOND) { PIreg_int += KiTs * PIreg_err; PIreg_int = saturate(PIreg_int,MIN_OUTPUT,MAX_OUTPUT); setPWM(saturate(PIreg_prop + PIreg_int); state = FIRST; } Nel codice che hai postato, l'implementazione è in virgola mobile, peraltro in formato double (immagino che lì corrisponda a 32 bit), quindi sarà molto lenta. Implementare in virgola fissa richiede un po' di sforzo, ma la differenza nel tempo di esecuzione è molto marcata. Qui non riesco adesso a fare un esempio, o meglio devo cercarlo, dovrei averne uno funzionante. Modificato: 6 ottobre 2019 da Sandro Calligaro Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 6 ottobre 2019 Autore Segnala Share Inserita: 6 ottobre 2019 Direi che per il momento cerco di fare un controllo di corrente con Arduino alla luce dei consigli che mi avete dato, modifichero la libreria in modo da togliere i double e fare i calcoli in virgola fissa, vediamo se viene fuori qualcosa di utilizzabile. Al limite provo a scrivermela. Se rimane lento passo a un processore a 32 bit tipo fishino. Link al commento Condividi su altri siti More sharing options...
marcoc4d Inserita: 7 ottobre 2019 Autore Segnala Share Inserita: 7 ottobre 2019 Aggiornamento: ho modificato la libreria del pid facendola in virgola fissa e le cose sono migliorate parecchio, il tempo di calcolo del pid é sceso a 65µs. Direi che ora provo a leggere i segnali dei due sensori hall mentre il motore va ad anello aperto per capire come sono utilizzabili. Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati
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 accountAccedi
Hai già un account? Accedi qui.
Accedi ora