Il servo risponde al servo tester, non al microcontrollore. I segnali sembrano uguali


8

Ho un servo TowerPro MG90D ( Link del produttore ) ( Link ServoDatabase ).
Ha un intervallo di 180 gradi (non continuo).

TowerPro MG90D

Risponde perfettamente al mio servo tester:
Servo tester

Osservare il seguente Duty Cycle al 7% (circa 90 gradi) sul tester:

servo tester di portata

servo tester di portata

Il servo risponde bene.


Tuttavia, quando uso servo.write()con il mio clone Arduino Mega 2560, il servo non risponde a nessun angolo di uscita. Ho diversi altri servi che funzionano perfettamente con lo stesso codice sugli stessi pin.

Osservare il seguente Duty Cycle al 7% su Arduino con servo.write(90):

portata arduino servo 90 gradi

Nessuna risposta. Il servo è "inerte"; non mantiene alcuna posizione.


Mentre stavo scrivendo questa domanda, ho pensato di provare servo.writeMicroseconds().

Ecco qui servo.writeMicroseconds(1450):

scope arduino servo 1450ms

Il servo risponde!

Ecco servo.writeMicroseconds(1472)(funzionante), che ha gli stessi intervalli di tempo del precedente non funzionante servo.write(90)!

scope arduino servo 1472ms

servo.writeMicroseconds(1550) (Lavorando):

scope arduino servo 1550ms


Qual è la differenza?
Il servo tester funzionava a 49,5Hz, mentre servo.write()falliva a 49,9Hz. Mi chiedevo se in qualche modo quel 0.4Hz facesse la differenza, ma poi vedo che servo.writeMicroseconds()funzionava anche a 49.9Hz.

Nelle acquisizioni di ambito di cui sopra, si può vedere che entrambi servo.write(90)e servo.writeMicroseconds(1472)hanno gli stessi intervalli di tempo:
 1,474,560ns HIGH
18,544,640ns LOW

I segnali sono così simili ... Cosa potrebbe causare il servo.write()mancato funzionamento?

Il mio codice è il più semplice possibile:

#include <Servo.h>
Servo serv1;

void setup() {
  serv1.attach(3); // Pin 3
}

void loop() {
  serv1.write(90); // No response
  delay(3000);

  serv1.writeMicroseconds(1472); // Works
  delay(3000);

  serv1.write(0); // No response
  delay(3000);

  serv1.writeMicroseconds(1800); // Works
  delay(3000);
}

schematico

simula questo circuito - Schema creato usando CircuitLab


Ho provato entrambi un alimentatore lineare da banco e ho anche provato a utilizzare un convertitore buck per scendere da 9V.
Bort

1
Sei sicuro di avere un'onda costante per tutti i 3 secondi quando lo usi write? Non c'è davvero motivo per cui il servo non funzioni, quindi metterei in dubbio i tuoi segnali.
Dmitry Grigoryev il

1
@Bort Allora non riesco a credere alla tua storia.
Dmitry Grigoryev il

2
@BigHomie: i segnali sono identici per quanto riguarda le immagini dell'oscilloscopio. Sta succedendo qualcosa oltre al segnale. La scarsa qualità è una cosa che potrebbe causare reazioni diverse a segnali nominalmente identici.
JRE,

2
Se possibile, acquisire due tracce dell'oscilloscopio sulla linea del segnale servo con il servo collegato . Una traccia con solo serv1.write () e una traccia con solo serv1.writeMicroseconds (). Pubblica entrambe le tracce. Per un ulteriore fascino, getta una terza traccia dal tuo tester con il servo collegato .
Neonzeon,

Risposte:


0

Innanzitutto, una rapida parte. Sembra che tu abbia una leggera incomprensione su come funzionano i servi. I servi non sono controllati da PWM e non sanno né si preoccupano che stai inviando impulsi a 49. qualunque sia Hz. Non sanno che l'impulso è una percentuale di un certo periodo arbitrario. Al servo non potrebbe importare di meno il tempo che intercorre tra gli impulsi. Lo dico perché sembri insolitamente concentrato su cose che in realtà non contano.

I servi non sanno nemmeno o si preoccupano che la tensione sia alta o bassa in un dato momento. Si preoccupano solo di una cosa: il tempo tra un fronte di salita e un di discesa.

Il servo viene controllato rilevando un fronte di tensione in aumento e misurando il tempo fino a quando non vi è un fronte di discesa. I tempi validi sono in genere compresi tra 1,0 e 2,0 ms, ma possono variare da servo a servo.

Puoi controllarlo a 1Hz, 10Hz, 50Hz, 100Hz. La maggior parte risponderà a pulsazioni ancora più elevate, ma ancora una volta questo è variabile. Quello che sto cercando di dire è che la frequenza, il duty cycle, la durata tra gli impulsi, non potrebbe essere meno rilevante per il tuo problema, ovvero che il servo non risponde quando te lo aspetti.

L'unica cosa rilevante sono i bordi del polso, a cui non hai prestato attenzione. Se vuoi capirlo, ti preghiamo di iniziare a guardare le cose che contano, dare da vicino acquisizioni dei bordi del polso, quel genere di cose. Non hai catturato nulla di utile in quelle schermate, motivo per cui non sembra esserci un problema o una differenza. Ci sono molti problemi o differenze che non sarebbero mai visibili con ciò che hai misurato.

Quello che posso vedere è che la cattura del treno di impulsi non funzionante è notevolmente più sporca, sia del polso che del suolo, rispetto a qualsiasi altra. Il che è strano, come dovrebbe chiamare la stessa funzione degli altri. Perché quello è tanto più rumoroso?

Ancora più importante, nella cattura non lavorativa, guarda il "tempo di caduta". 809μs? L'oscilloscopio ritiene di vedere un tempo di caduta della durata di 0,8 ms. Non va bene. Chiaramente ciò non è corretto, ma il fatto rimane, questo è ciò che misura.

Questo è un classico segno di un bordo sporco. Pensaci. Se questo impulso sta ingannando la tua attrezzatura di prova di fascia alta che è l'oscilloscopio nel vedere un bordo ridicolmente lungo o un tempo di caduta, o forse così sporco da non riuscire a rilevare correttamente il fronte di caduta per tutto il tempo (o chi lo sa), allora che possibilità ha quel povero servo da $ 8 di schifo di ottenere un decente margine di caduta?

Se un servo non ottiene un impulso valido (come se il fronte di discesa impiega troppo tempo, è troppo sporco o è perso) all'interno dell'intervallo di impulsi accettabile e dai servi che calcolano per i bordi che possono o meno avere qualcosa da fai con quello che consideri i bordi del polso, quindi risponde come se fosse spento.

In altre parole, non solo non si muove, ma non resisterà al movimento dell'albero. Sarà semplicemente inerte, esattamente come stai vedendo.

Ora, questo fa sorgere la domanda .... perché la chiamata a servo.write influirebbe sulla qualità dei bordi?

Hai detto un clone. Come questo?inserisci qui la descrizione dell'immagine

Questi cloni in particolare tendono a comportarsi in modo irregolare a causa del disaccoppiamento incredibilmente scarso. Dovrebbero esserci disaccoppiatori di condensatori su ogni pin di alimentazione e il più vicino possibile al mega2560. E sul vero arduino, in effetti ci sono. Su questi cloni, tuttavia, sono troppo lontani, o forse mancanti, è difficile da dire. È ovvio guardando la lavagna che non si comporterà in modo affidabile, questa è la cosa importante.

Ma qual è la differenza però?

Quando chiami servo.write, lo stack viene spostato più in alto rispetto a quando scrivi callMicroseconds. Dato il puntatore dello stack a 3 byte del mega2560 (17 bit), è necessario capovolgere un mucchio di bit critici che non è necessario quando si chiamano writeemicrosecondi. So che questa sembra una differenza improbabile, ma ho sperimentato la mia giusta dose di microcontrollori scarsamente disaccoppiati, e in particolare gli atmega sembrano esibire un comportamento strano specificamente quando si usano i timer e / o spingendo o facendo scoppiare lo stack. Qualcosa di simile è successo per me, solo lo stack è stato danneggiato quando stavo cercando di guidare i LED con PWM, ma se ho messo tutto in linea senza spingere lo stack, ha funzionato. Il disaccoppiamento era alla fine il problema.

Mi aspetterei pienamente che il disaccoppiamento disagiato sia in grado, per ragioni note a quell'atmega2560 e nessun altro, di avere un effetto dannoso sulla qualità del bordo di quell'impulso, ma solo quando si sta spingendo lo stack prima. Questo servo non è in grado di gestire il modo in cui questi bordi vengono macchiati, quindi non vede impulsi validi in quel caso. Altri servi ovviamente lo gestiscono.

Il disaccoppiamento delle cose è sempre bizzarro e iper specifico come questo. Ecco perché il disaccoppiamento è così importante. Mantieni l'inferno da incubo di problemi che la mancanza di capacità può farti venire a bada con bei tappi di ceramica grassa e il più vicino possibile al chip come fisicamente possibile.


0

Ciò può essere correlato alle impostazioni dei pin di output effettuate dalla routine .write (). Prova a utilizzare un resistore pull-down 1K, non funziona, quindi rimuovilo e usalo come resistore pull-up. questo bilancerà l'effetto di qualsiasi resistore pull-up / pull-down della settimana interna che può essere impostato dalla routine. Quando si misura il segnale con l'oscilloscopio, la resistenza interna della sonda agisce come un pull-down.
La maggior parte dei servi rilascia anche l'alimentazione al motore interno se il segnale non è preimpostato per 10 impulsi di fila. Questo è usato per risparmiare energia.


Temo che la tua risposta non sia corretta. servo.write () accetta un angolo come input, non tempo. Le persone non dovrebbero votare le risposte alla cieca.
Bort

Sì, errore mio, non ho letto bene il codice. ciò può essere correlato alle impostazioni dei pin di output effettuate dalla routine .write ().
555

2
Questo sarebbe stato il mio primo pensiero, tuttavia le tracce dell'ambito sembrano confutare questo. Una terra mancante e una diversa situazione di pull-up / -down potrebbero spiegare lo stesso segnale inviato ma non arrivare lì (dopo la posizione della sonda).
KalleMP,

Penso che @ KallieMP abbia probabilmente ragione. I resistori pullup / down potrebbero benissimo essere la risposta. Potrebbero limitare la corrente. Gli impulsi possono essere formati correttamente ma con un azionamento insufficiente. Quindi, indipendentemente dalla particolare funzione di servo.write (), i livelli attuali devono corrispondere esattamente all'output del servo tester per ottenere lo stesso risultato.
SDsolar,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.