![]() |
|
Dopo aver saldato le resistenze sarete davanti a una scelta:
- Lavorare empiricamente per trovare il valore i di servo.write(i); che ferma i motori
- Saldare due cavi ai poli del motore e collegarli a due porte analogiche
La prima scelta evita l'utilizzo di due porte analogiche e due saldature, ma comporta un lavoro di setting per trovare il valore i di servo.write(i); che ferma i motori. Questo valore cambierà nel tempo in base al voltaggio di alimentazione, temperatura dei servomotori, umidità dell'aria ecc. ecc. per questo motivo risulta spesso straziante trovare il valore corretto.
Il codice:
int i = 90; // modifica il valore se il motore non sta fermo finchè non sta fermo Servo.write(i);
In caso di insuccesso il robot invece che stare fermo tremerà leggermente o girerà leggermente in una direzione, o su se stesso. Per questi motivi consiglio la seconda scelta.
La seconda scelta consiste nel saldare due cavi (di diametro esterno isolante compreso di massimo 1mm, vedi cavi interni a plug usb / cavi da porta seriale) ai poli del motore all'interno del servo, fare un foro nella cassa del servomotore per far passare i cavi e collegarli come in figura:

Da questi due cavi potrete percepire dalle porte analogiche la corrente presente nel circuito di alimentazione del motore e rendere piu' preciso il vostro robot aggiungendo un input importantissimo al vostro automa. Questi due valori variano in rapporto a quanto ruota il motore e in che direzione. Molto semplicemente, se alimentiamo il servomotore dalla porta 5v di arduino, otterremo dei valori che variano tra 0.25v e 4.35v. Se il motore è a piena potenza in una direzione otterremo 4.35v in una delle due porte e 0.25v nell'altra. Se il motore è perfettamente fermo otterremo 2.35v in entrambe le porte. Se il motore è a piena potenza nella direzione opposta otterremo 0.25v in una e 4.35v nell'altra.
L'algoritmo D.I.R (Differential Input Regulator)
Questa tecnica assomiglia molto al metodo utilizzato per far stare in piedi il robot Self balancing per principianti.
Il concetto di base è fare un calcolo differenziale di due valori inversamente proporzionali e modificare i finchè la lettura di polo1 sarà identica a quella di polo2. In questa situazione il motore sarà perfettamente fermo. In questo caso il valore di i smette di essere determinante e diventa relativo alla corrente percepita dalle due porte.
Dati:
porta1 4.35v porta2 0.25v = avanti tutta
porta1 2.35v porta2 2.35v = motori fermi
porta1 0.25v porta2 4.35v = indietro tutta
Soluzione:
servostop() {
int polo1 = analogRead(0); // lettura polo1
int polo2 = analogRead(1); // lettura polo2
if(polo1 > polo2) i = i + 1; //se polo1 > di polo2 accelera
if (polo2 > polo1) i = i - 1; //se polo2 > di polo1 rallenta
servo.write(i); // chiaramente se polo1 == polo2 il motore si ferma
}
Appena viene eseguito il programma il servo girerà alla massima velocità in una direzione, inizerà a percepire i due poli e a diminuire il valore di i fino a fermare il servo. Questo rimarrà per sempre fermo :P (non avete idea di quante ore possono risparmiarvi queste poche righe di codice, sono due anni che mi perseguitavano i servomotori affetti dal parkinson in posizione di stop).
Come potete vedere nella funzione servostop() si regola dinamicamente il valore di i fino ad ottenere un valore differenziale nullo tra polo1 e polo2 (cioè polo1 - polo2 = 0). Questo sistema non è studiato solo per avere una gestione comoda della posizione di stop, ma è pensato anche per dare un feedback sul movimento del robot. Sto ancora facendo i calcoli ma credo che con 4 righe si potrà avere un rapporto di conversione volt / millis in m /sec o km /h. Fatto questo si potrà ottenere un input simile a quello che si otterrebbe con un encoder e quindi iniziare a pensare ai primi esperimenti di mapping ;). E' ancora in fase di sperimentazione la risposta del sistema in momenti di alto assorbimento (ruote bloccate da ostacoli ecc.).

DIR Servo modification by Giovanni Blu Mitolo is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
Based on a work at www.gioblu.com.
