Arduino: Quadrature encoder e PID

Salve ho intenzione di utilizzare Arduino per implementare un controllo di un motore in DC, opportunamente pilotato (L298), con acquisizione di due segnali in quadratura per il controllo della velocità e della posizione. Il motore gira ad una velocità di 4000 giri/min. Il mio dubbio è: riesce Arduino a leggere i segnali di input a frequenze di tale entità? Ci rimangono abbastanza cicli macchina per implementare un algoritmo PID per la regolazione della velocità? E se volessi comandare due motori? Grazie a chiunque voglia dami info. Michele

Solitamente queste cose si fanno con MCU che hanno un modulo hardware chiamato QEI (quadrature encoder interface) e usando compilatori C che non fanno uso di librerie (si accede manualmente ai registri) perchè tutto ciò ti fa risparmiare cicli macchina. Inoltre e consigliabile usare (se parliamo di CPU 8 bit dell'ordine dei 20 mHz) una micro per ogni motore.

Comunque , in base all'applicazione e alle prestazioni richieste, si può fare anche con un'unica MCU senza QEI (l'ho visto fare con micro molto meno potenti di Arduino). In ogni caso conviene farsi i conti, come giustamente chiedevi tu, ma non è una cosa delle più banali, sopratutto perchè è difficile stimare quanti cicli sprecano le routine.

Se posso darti un cosiglio "a naso": se usi un encoder che non supera le 50 cpr, montato dopo la riduzione meccanica (o prima, ma rimanendo sempre intorno la stessa risoluzione equivalente), lasci stare la quatratura e non vai oltre la frequenza dei 100Hz per la routine del PID (cioè eseguendolo al massimo 1 volta ogni 10 ms) ci riesci sicurmente. Capisci bene però che non si parla certo di un controllo di quelli eccezonali (un encoder da 50 cpr è un prodotto per hobbysta) Eventualmente se vedi che le cose fungono, provi ad aumentare le prestazioni del PID.

Sulla documentazione , nel sito di arduino c'è un progetto con un encoder in quadratura di buona risoluzione (credo 1024), ma per il discorso in questione non fa testo perchè si tratta solo di un esempio di acquisizione, non è trattano nessun controllo. Dacci un occhiata comunque.

Il motore che devo controllare è dotato di due fotosensori (a 90° uno rispetto all'altro) che "leggono" tre finestre poste sull'asse (cpr=3?). Il segnale proveniente dai sensori è quindi a 200 Hz. Pensi sia gestibile tale segnale? Con l'occasione (giuro che ho letto molto su Arduino ma non mi è ancora chiaro) una volta programmato trasmite USB è possibile scollegarla e far girare il programma memorizzato (anche dopo una rialimentazione?. Grazie e ciao

Michele

Il motore che devo controllare è dotato di due fotosensori (a 90° uno rispetto all'altro) che "leggono" tre finestre poste sull'asse (cpr=3?). Il segnale proveniente dai sensori è quindi a 200 Hz. Pensi sia gestibile tale segnale?

Se sono il tipo di motore che credo (l'encoder non è ottico ma ad effetto hall) l'ecoder è montato prima della riduzione meccanica, quindi per ogni giro alla ruota ne hai molti di più prima della riduzione, ciò significa molti più cpr. Verifica questa cosa, ed eventualmente il valore del rapporto di riduzione, così rifacciamo i conti.

In ogni caso, per quello che ne so io con una MCU come quella che equipaggia Arduino non è consigliabile andare oltre la decodifica di un segnale di 10 kHz o giù di li, specie se vuoi controllare due motori.

Ma di che applicazione stiamo parlando? Perchè in ogni caso siamo sempre su un controllo mediocre e non se ne parla di sfruttare la MCU per altre operazioni, se non quella di comunicazione con l'esterno per ricevere il riferimento e ritornare qualche velore.

PS: se sei capace di bypassare le librerie di arduino e scrivere il codice in C standard (ma ciò necessita la conoscenza approfondita dell'architettura, quindi si perde il vantaggio di usare arduino), oltre a fare le divisioni in maniera oculata, è possibile spremere ancora di più la cpu.

Ok. Ti dettaglio il tutto. Alcuni anni fa (due decenni fa per la precisione) ad una fiera dell’elettronica ho acquistato un robot antropomorfo alto circa 1 metro. Il robot prodotto da una ditta chiamata SIRIUS di Monza si chiamava MODDY ed è dotato di una base con due motori e due braccia con sei gradi di libertà. Ogni grado di libertà è comandato da un motore a DC completo di riduttore e sull’asse (del motore non in uscita dal riduttore) ci sono due barriere ottiche diodo-fotodiodo. Ogni coppia di motori è comandata da una scheda con CPU 8051. Purtroppo la documentazione che mi fu fornita era scarsa e a parte il movimento della base non sono mai riuscito a far muovere niente altro. Il robot è rimasto abbandonato per anni durante i quali mi sono occupato di varie cose, tra le altre di laurearmi in informatica e di approfondire diversi aspetti di AI. In questi giorni ho “riesumato” Moddy deciso a sostituire la parte di pilotaggio dei motori e, girando su Internet, mi sono imbattuto in Arduino con il quale appunto vorrei pilotare le braccia di Moddy.
Tornando all’aspetto tecnico (spero di non aver annoioato nessuno in questa divagazione storica) le barriere ottiche sono prima del riduttore e il fascio del diodo viene interrotto 3 volte ogni giro del motore che gira a 4000 giri al minuto. Quindi ogni secondo il motore compie circa 67 giri, la barriera genera 3 impulsi/giro quindi 200 impulsi al secondo. Tutto questo indipendendentemente dal rapporto del riduttore, che centrerà successivamente (PID, positioning ecc).
Quindi dovrei essere ben lontano dai 10 Khz a cui accennavi tu.

Commetto errori?

PS: La ditta Sirius probabilmente era già fallita quando ho acquistato il robot. Forse negli anni 80 è stato prematuro proporre un home-robot (che costava circa 10 milioni di lire) e probabilmente sarebbe fallita anche oggi. :’(
Non so quanti esemplari sono stati prodotti di questo robot. Sta di fatto che in intenet purtoppo non c’e traccia.

Ciao
Michele

Fighissimo il robot anni 80 con le braccia a 6 gradi di libertà :)....caspita, io vorrei acquistare un piccolo manipolatore 5 e ci vogliono 500 euro...

Per quanto riguarda il motore stiamo dicendo la stessa cosa (almeno credo): se l'encoder è prima della riduzione (cioè sul rotore del motore DC), ogni tre giri del rotore l'encoder fa 3 impulsi, ma a te interessa controllare la velocità dopo la riduzione meccanica (alla ruota del robot), quindi [u]è quello l'asse di cui vuoi controllare la velocità[/u], che girerà più lento del rotore. Quindi, come ti dicevo prima, per x giri della ruota del robot corrispondono r*x giri del rotore --> 3*r*x impulsi --> 4*3*r*x impulsi in quadratura.

Prova a vedere in rete se tovi informazioni sul motore inoltre vedi se c'è stampato da qualche parte il valore della riduzione

Il rapporto del riduttore è 64:1. Ma cosa ha a che fare con il segnale che Arduino deve acquisire? La frequenza del segnale proveniente dalle barriere ottiche è indipendente dal rapporto di riduzione. Ovviamente è importante per la regolazione finale del numero di giri in uscita dal riduttore. Ma ripropongo la domanda. Un segnale (in effetti due dato che le barriere ottiche sono due per motore) a 200 Hz è gestibile da ARDUINO?.

Ciao Michele

ok c'e stato un equivoco :P i 4000 giri/minuto sono già riferiti al rotore ovviamente....solo che in genere, quando si parla, ci si riferisce sempre a quelli dopo il riduttore. Ricontrollando alcuni datasheet di motori simili al tuo, mi sono accorto che avevo perso gli ordini di grandezza ::) gli rpm dopo il riduttore sono sensibilmente inferiori, mentre quelli del rotore vanno generalmente dai 4000 ai 6000. Tutto risolto quindi, con Arduino dovresti riuscire tranquillamente a gestire anche la quadratura per entrambe i motori.

Ok. Terrò questo topic aggiornato man mano che ci saranno sviluppi. Prenderò anche arduino motor shield che è idoneo a pilotare due motori e predisposto per l'ingresso da decoder in quadratura. Grazie per le info. Ciao

Michele

... Prenderò anche arduino motor shield che è idoneo a pilotare due motori e predisposto per l'ingresso da decoder in quadratura. Grazie per le info. Ciao

Michele

Anttento alle correnti assorbite dai motori. Il motor shield se non sbaglio è equipaggiato con L293D che non è che possa sopportare grosse correnti. Prima vedi di riuscire a trovare info sui motori.

PS: ma questi motori motorizzavano la base, quindi avevano su, tutto il peso del robot che è alto un metro. Insomma quanto pesa il tutto? Dubito che i motori siano di quelli gestibili con un L293; penso ci voglia qualcosa di più grosso.

No il sistema che devo implementare mi serve per le braccia del robot. I motori sono Buehler e mi smbrano quelli del link sotto (purtroppo sul motore c'è solo la marca ma non il tipo): http://www.buehlermotor.de/Webpage/ywmediabase.nsf/398b73fcedadd1d3c1256ddd004563b0/A2B571E5F8E61DC2C125738000365EC5/$file/1_13_078_EN.pdf

Per la corrente assorbita mi conviene fare un a misura reale e verificare con il datasheet del L293D. Ciao Michele

Se sono questi i motori, con il 293 ci riesci, sei entro i limiti (wow…il datasheet è molto completo, da pure le costanti di tempo, cosa che pocchissimi produttori fanno).
Ma come mai non sfrutti l’elettronica che c’era gia? E’ osoleta o fuori uso?

Ci ho provato ad usare la sua elettronica. Purtroppo non ho molta documentazione del robot e quindi non sono mai riuscito a far funzionare nulla al di fuori della base. L'architettura del sistema è composta da una scheda principale che controlla i due motori per lo spostamento del robot dalla quale parte un bus seriale che comunica con le varie schede, ognuna con una MCU 80C51, per il comandao della braccia. Ogni scheda pilota tre motori. La base è dotata di ingresso seriale per la comunicazione RS232 con il PC. Purtroppo non ho informazioni sul protocollo di comunicasione base-schede e non ho la possibilità (e neanche la voglia) di vedere all'interno della MCU per ricavarlo. Il mie intenti sono quindi di sostituire il tutto con la configurazione seguente: - 1 scheda Arduino per la gestione di uno o due o tre motori (dipenderà dalle prove che farò); - 1 scheda Arduino per che si occuperà dell'interfacciamento via cavo o etere verso il PC e la gestirà i vari Arduino di comando dei motori; - 1 scheda MD23 (Devantech) per il comando dei motori della base (la uso solo perchè l'ho acquistata prima di scoprire Arduino);

Sul PC girerà il programma che si occupera della gestione ad alto livello del robot. Per questa parte sto pensando all'approccio fuzzy per risolvere i vari problemi (ad esempio la cinematica inversa).

Il passo successivo, anche se ci sto già lavorando, è l'utilizzo di muscoli ad aria. Ne sto costruendo uno con gia incorporato un sensore di feedback per la posizione. Ovviamente tutto gestito da Arduino. Se sarà di interesse scriverò su questo forum. Mi piace l'approccio open source.

Ciao Michele

Non è una cattiva idea sostituire parte dell'elettronica visto che Arduino non costa davvero nulla! Magari puoi provare a recuperare solo le schede di potenza (i ponti H) dei motori.

L'Md23 mi pare un ottima scelta per i motori della base.

La fazzy per la cinematica inversa invece mi sembra un pò avventata :D Si tratta di quazioni che sono difficili da scrivere, ma semplici da risolvere, come si è sempre fatto in questi casi; Cmq sperimentando ci si diverte sempre. :)