vibrazioni e ronzii su servo sg90

Sto usando due servo SG90 e funzionano bene. Uso la libreria servo.h.
Però a volte, e non solo agli estremi del movimento di rotazione (ho ridotto infatti a 20-80 per stare in range molto sicuro), dopo aver raggiunto la posizione, emette un ronzio e piccole vibrazioni, come se dovesse aggiustare meglio la sua posizione. (Non ci sono ostacoli che gli impediscono di raggiungerla).

Per ora ho risolto facendo un detach del servo ogni volta che ha raggiunto la posizione voluta, poi rifaccio l'attach quando mi serve cambiarla di nuovo: funziona benissimo.
Però chiedevo se c'è un metodo più 'pulito' e corretto invece del mio workaround.

Hai comprato dei servo ciofeca che fanno esattamente quello che devono fare, le ciofeche. :slight_smile:

Questo lo sapevo fin dall'inizio e vanno benissimo per quello che devono fare. :wink: Praticamente li uso come attuatori lineari per spostare un perno: nessuna precisione assoluta né movimenti da vero servo. Ne devo mettere molti per cui mi interessava il minor prezzo.
Del resto, ho risolto comunque.
Chiedevo solo se c'era qualche ulteriore prova da poter fare: ad esempio avevo letto di usare un codice come questo per avere più precisione negli impulsi rispetto alla libreria. Dicevano che può essere un jitter dovuto alla modulazione di Arduino nell'ordine di 10us.

cli();
long start = micros();
digitalWrite(servoPin, HIGH);
while (micros() - start < duration)
  ;
digitalWrite(servoPin, LOW);
sei();

Che valori di duration devo mettere per avere un range accettabile da un servo, tipo quello sopra 20-80?

franketto:
Del resto, ho risolto comunque.

Come ? Può essere utile per altri che potrebbero avere lo stesso problema e cercano la soluzione nel forum

Ciao nid69ita.
bè, l'avevo già scritto nel primo post :wink:
Ho risolto facendo un detach ogni volta... Non è la procedura standard e corretta, però funziona molto bene!

Tra l'altro ho scoperto che la vibrazione succede solo con certi valori precisi, tipo nel mio:
25,26 e 90,91,92,93
A quel punto, non dovendo lavorare di precisione, è sufficiente fare un 24 o un 27 oppure un 89 o 94 e si è a posto!
Preferisco comunque fare anche un detach perché ho visto in video che sono molto sensibili a interferenze varie, per cui col detach sono sicuro che non si muovono più :wink:

Richiedo comunque ancora il valore da mettere sul duration del post 2, che vorrei fare quel test per curiosità.

Ho provato un qualche sketch, ma non so se so bene cosa faccio :slight_smile:
Infatti non va...

void servoSinglePulse(int duration = 1500){
  //cli();
  long start = micros();
  digitalWriteFast(servoPin, HIGH);
  while (micros() - start < duration)
    ;
  digitalWriteFast(servoPin, LOW);
  //sei();
}

bool doit = 1;
void servoSinglePulse(int durataImpulso = 1500);  

void loop() {
  
  if (doit ==1) {
    
    doit = 0;
    int durataImpulso = 1000; // durata impulso in us
      
    long durataCiclo = micros();  
    cli();
    while ( (micros() - durataCiclo) < 1000000  ) {
    
      long delayBase = micros(); 
      while (micros() - delayBase < (20000 - durataImpulso) ) {
        // attesa totale di 20ms=20000us
        ;
      }
     servoSinglePulse(durataImpulso);    
    
    }
    sei();        
  }
    
}

Ho provato a simulare, disabilitando gli interrupt per cercare di avere una maggiore precisione nel jitter, la serie di impulsi della durata complessiva di circa 20us, con il pin HIGH per una durata variabile, posizione centrale 1500, (range teorico 500-2500).
Per testare ho provato una serie di impulsi per 1 solo secondo. Risultato si blocca all'interno del ciclo dopo il cli()... (Se tolgo cli e sei, funziona, ma il servo si sposta oscillando molto nella posizione centrale e all'uscita dal ciclo ritorna verso gli 80° (?) ).

Qualcuno mi dà qualche consiglio?
E' la prima volta che uso cli/sei e micros su Arduino e pure la prima volta che piloto un servo, quindi... :slight_smile: :wink:

PS:
Tutto è nato da questo post con parte del codice sopra: