Controllo_velocita'_motore_dc

Buona sera, ho intenzione (per scopi puramente didattici) di intraprendere un controllo di velocità, utilizzando arduino uno, su un motore dc. Attualmente non ho scelto ne il motore da retroazionare e nemmeno il tipo di encoder da utilizzare (per avere suggerimenti in merito, ho aperto un post nella seione hardware), ma volevo comunque iniziare a stendere il programma, almeno per la lettura della velocita' da encoder. A proposito di questo, per effettuare una corretta lettura di velocita' da encoder vorrei utilizzare l'interrupt (attivo sul fronte di salita), nel modo seguente:

  • Avviene il primo fronte di salita, quindi parte l'interrupt, nella funzione interrupt contero' l'impulso e contero' il tempo;

  • Quando avviene il secondo interrupt con il tempo ottenuto calcolerò la velocita';

Per la lettura del tempo userei micros();

Per quando riguarda il controllore, vorrei discretizzare un PID, ma questo poi lo vediamo, per ora vorrei essere 'massacrato' per la marea di cazzate dette :) Scatenatevi se volete!

La soluzione va bene, la funzione micros() va bene, puoi anche usare un'altra soluzione molto simile: se usi un sensore ottico realizza il disco con delle lunghe scanalature invece che con dei fori/tacche , in questo modo usa un fronte dell'interrupt per far partire il timer e l'altro fronte per lo stop

Ciao Icio, grazie per la risposta! Non ho molta praticita' quindi penso che utilizzero' un classico encoder ottico rotativo, economico. Il punto è che non ho ancora scelto che motore dc usare, in quanto mi è stato detto che con Arduino posso controllare solo qualcosa che vada 'piano', quindi non so' neanche da dove iniziare per la scelta del motore e di conseguenza non posso scegliere l'encoder, potresti consigliarmi qualcosa? Non ho particolari esigenze voglio solo avere la soddisfazione di provare che cio' che ho studiato si applica davvero :) grazie per la disponibilita'

In realtà con Arduino direttamente non puoi controllare (quasi) nessun motore, ma ti devi avvalere di una fonte di energia esterna, tipo una batteria, e di un transistor (o di un ponte h, se vuoi anche controllare il senso di rotazione). In questo modo Arduino non deve dare l'energia al motore, ma si limita a aprire e chiudere il circuito del motore attraverso il transitor, che è come un'interruttore controllabile da Arduino. A questo punto tutto dipende dal transistor e dalla corrente/tensione che può sopportare. Per concludere, con Arduino e il transistor giusto puoi controllare tutto. Ricordati di mettere un diodo per evitare di danneggiare il transistor, ma questa è un'altra cosa. Se non è chiaro, chiedi e ti invio uno schema.

Ciao Ptia, grazie per l'intervento! Si, nella fretta ho dimenticato di scrivere che avrei utilizzato comunque un ponte ad H, o un transistor con diodo di ricircolo (la teoria a volonta' :) ma la pratica aimè 0.00000001)! I miei dubbi sulla non fattibilita' del controllo tramite arduino, risiedono piu' dal punto di vista della rapidita' di calcolo (penso), per questo vorrei che mi aiutaste ad indirizzarmi su un motore fattibile a livello di controllo con arduino! Che ne pensi?

Non so consigliarti su un motore in particolare, in effetti interrupt troppo vicini si potrebbero accavallare e, visto che mentre si esegue la funzione dell'interrupt gli interrupt sono disabilitati, ci possono essere problemi. La soluzione potrebbe essere cercare di portare più calcoli possibili fuori dagli interrupt e dentro al loop, limitandosi, dentro gli interrupt, a registrare i micros() di quando arriva un segnale.

long microsImpulsoPrecedente;
long microsUltimoImpulso;
void nuovoImpulso() {
   microsImpulsoPrecedente = microsUltimoImpulso;
   microsUltimoImpulso = micros();
}
void loop() {
   int velocita = microsUltimoImpulso-microsImpulsoPrecedente;
   //tutti i calcoli andrebbero qui
}

Dove nuovoImpulso è l'interrupt

generalmente un interrupt è una funzione molto lenta e in questo caso inutile. Se ben gestito puoi prelevare tempi anche nell'ordine del nanosecondo quindi più che sufficiente per i motori+encoder da hobbysta. Quindi la prima cosa da fare è capire cosa si vuole fare!

Ptia, si avevo pensato a qualcosa del genere, adesso in attesa che qualcuno mi indirizzi su cosa acquistare iniziavo a pormi qualche domanda, del tipo:

-Da quanto mi è stato gentilmente detto nel forum, Arduino considerando il tempo di conversione dell'ADC e il tempo per effettuare le varie operazioni si spinge fino al max di 2000-3000 cicli al secondo, cioè quindi 2-3 Khz, quindi in base a questo potrei scegliere il tempo di campionamento diciamo per essere sicuri sui 200Hz?? -Se ipotizzo di controllare in velocità un motore dc 'lento' diciamo da 100rpm, quindi 1,67Hz (non so' se ho detto una fesseria, nel senso se esistono davvero), utilizzando un encoder avente ipotizziamo 10 settori, avro' quando il motore gira alla max velocita' un numero di interrupt pari a 1,67*10=16,7 interrupt al secondo, è giusto come ragionamento fin qui?? Prima di andare al prossimo step attendo correzioni su quanto scritto

Iociprovo: I miei dubbi sulla non fattibilita' del controllo tramite arduino, risiedono piu' dal punto di vista della rapidita' di calcolo (penso), per questo vorrei che mi aiutaste ad indirizzarmi su un motore fattibile a livello di controllo con arduino! Che ne pensi?

Scusate ma non capisco bene... Qui sicuramente ci sono utenti ben più esperti di me, ma nel caso semplice del nostro amico, per un encoder disc da (diciamo) 24 tacche montato su un motorino DC che a dir tanto farà 10 giri al secondo (farà girare una ruota penso, non volare un aereo :D ed il disco lo metterà sulla ruota dopo la demoltiplica), sono 240 Hz, per cui non capisco i microsecondi e il discorso della sovrapposizione degli interrupt. Se poi la funzione agganciata all'interrupt fa solo un "contatore++;" quanto volete che ci metta? A questo punto ad intervalli regolari (es. 1 secondo) leggi il contatore, da questo calcoli la velocità: se l'intervallo "T" è in secondi (float), sai quanti fori ha il disco diciamo "F" (int), e hai letto "N" (int) eventi, calcoli la velocità V (long) in giri al minuto come V = (N/F)/T*60 e azzeri il contatore.

Mi sfugge qualcosa?

Iociprovo:
-Se ipotizzo di controllare in velocità un motore dc ‘lento’ diciamo da 100rpm, quindi 1,67Hz (non so’ se ho detto una fesseria, nel senso se esistono davvero), utilizzando un encoder avente ipotizziamo 10 settori, avro’ quando il motore gira alla max velocita’ un numero di interrupt pari a 1,67*10=16,7 interrupt al secondo, è giusto come ragionamento fin qui??
Prima di andare al prossimo step attendo correzioni su quanto scritto

ok è esatto , non ti preoccupare , genuino è più che sufficiente per realizzare il tuo progetto , se intendi anche aggiungere il controllo closed loop sulla corrente del motore l’ADC è anch’esso sufficiente

Buona sera, perdonate il ritardo, ma ho è periodo di esami e non ho avuto tempo! Allora, per il motore ho provveduto, cosi' come per l' H-Bridge, mentre per quanto riguarda l'encoder ancora nulla. Per una corretta scelta dell'encoder cosa devo tener presente? Diametro dell'albero del motore? altro?

Se parli del disco, si, dipende dall'albero del motore. Se parli del sensore ottico, se opti per un sensore a forcella devi fare attenzione allo spessore del disco, il mio è ad esempio da 3mm quindi l'interno della forcella deve avere una spaziatura maggiore, diciamo 5mm. Per il resto dipende da cosa vuoi collegarci, se il circuito lo fai tu o se vuoi un encoder pronto, io dopo alcune prove alla fine non avendo trovato nel negozio dalle mie parti (un GBC) un sensore a forcella utilizzabile (hanno solo quelli piccoli da 3mm e il disco struscia) ho optato per 2 di questi, che devono ancora arrivare: Speed Sensor Module EDIT: per i dischi in genere gli stepper e gli assi dei motori DC per i car kit hanno questo tipo di encoder disc: Disco per encoder di rotazione Quindi dipende da quali motori hai.