Eu tenho um servo TowerPro MG90D ( Link do fabricante ) ( Link do ServoDatabase ).
Possui uma faixa de 180 graus (não contínua).
Ele responde muito bem ao meu servo testador:
Observe o seguinte ciclo de trabalho de 7% (cerca de 90 graus) no testador:
Servo responde bem.
No entanto, quando uso servo.write()
com meu clone do Arduino Mega 2560, o servo não responde a nenhuma saída de ângulo. Eu tenho vários outros servos que funcionam muito bem com o mesmo código nos mesmos pinos.
Observe o seguinte ciclo de trabalho de 7% no Arduino com servo.write(90)
:
Sem resposta. O servo é "mole"; não está mantendo nenhuma posição.
Enquanto escrevia essa pergunta, pensei em tentar servo.writeMicroseconds()
.
Aqui está servo.writeMicroseconds(1450)
:
Servo responde!
Aqui está servo.writeMicroseconds(1472)
(trabalhando), que tem os mesmos intervalos de tempo que o prevoius que não funciona servo.write(90)
!
servo.writeMicroseconds(1550)
(trabalhando):
Qual é a diferença?
O servo testador trabalhou em 49,5Hz, enquanto servo.write()
falhou em 49,9Hz. Gostaria de saber se, de alguma forma, 0,4Hz fez alguma diferença, mas então vejo que servo.writeMicroseconds()
funcionou a 49,9Hz também.
Nas capturas de escopo acima, pode ser visto que ambos servo.write(90)
e servo.writeMicroseconds(1472)
têm os mesmos intervalos de tempo:
1,474,560ns HIGH
18,544,640ns LOW
Os sinais são tão parecidos ... O que poderia causar servo.write()
para não funcionar?
Meu código é o mais básico possível:
#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);
}
simular este circuito - esquemático criado usando o CircuitLab
write
? Não há realmente nenhuma razão para o servo não funcionar, então eu questionaria seus sinais.Respostas:
Primeiro, um rápido aparte. Você parece ter um leve mal-entendido sobre como os servos funcionam. Os servos não são controlados pelo PWM e não sabem nem se importam que você esteja enviando pulsos a 49 Hz. Eles não sabem que o pulso é uma porcentagem de algum período arbitrário. O servo não se importava com o tempo entre pulsos. Digo isso porque você parece incomumente focado em coisas que realmente não importam.
Servos nem mesmo sabem ou se importam que a tensão seja alta ou baixa em um determinado momento. Eles só se preocupam com uma coisa: o tempo entre uma borda ascendente e outra descendente.
O servo é controlado detectando uma borda de tensão crescente e medindo o tempo até que haja uma borda de queda. Os tempos válidos costumam estar entre 1,0 e 2,0ms, mas podem variar de servo para servo.
Você pode controlá-lo em 1Hz, 10Hz, 50Hz, 100Hz. A maioria responderá a taxas de pulso ainda mais altas, mas novamente isso é variável. O que estou tentando dizer é que a frequência, ciclo de trabalho, duração entre pulsos, tudo isso não poderia ser menos relevante para o seu problema, ou seja, o servo não está respondendo quando você espera.
A única coisa que é relevante são as extremidades do seu pulso, às quais você não prestou atenção. Se você quiser descobrir isso, comece olhando para as coisas que importam, dê capturas de perto de suas bordas de pulso, esse tipo de coisa. Você capturou nada útil nessas capturas de tela, e é provavelmente por isso que não parece haver um problema ou diferença. Existem muitos problemas ou diferenças que nunca seriam visíveis no que você mediu.
O que eu posso ver é que a captura do trem de pulsos que não funciona é visivelmente mais suja, tanto o pulso quanto o solo, do que qualquer um dos outros. O que é estranho, pois deveria estar chamando a mesma função que as outras. Por que isso é tão barulhento?
Mais importante, na captura não útil, observe o 'tempo de queda'. 809µs? Seu osciloscópio acha que vê um tempo de queda de 0,8 ms. Isso é mau. Claramente isso está incorreto, mas o fato permanece, é isso que ele mede.
Esse é um sinal clássico de uma borda suja. Pense nisso. Se esse pulso está enganando seu equipamento de teste de ponta, que é o seu osciloscópio, vendo uma borda ridiculamente longa ou um tempo de queda, ou talvez tão sujo, que simplesmente não consegue detectar corretamente a borda que cai o tempo todo (ou quem sabe), então Que chance esse pobre servo de US $ 8 tem de pegar uma vantagem decente?
Se um servo não obtiver um pulso válido (como se a borda de queda demorar muito, estiver muito suja ou estiver faltando) dentro da faixa de pulso aceitável, e pelos servos calculando as bordas que podem ou não ter algo a ver faça com o que você considera as bordas do pulso, e ele responde como se estivesse desligado.
Em outras palavras, não apenas ele não se move, como também não resiste ao movimento do eixo. Simplesmente será mole, exatamente como você está vendo.
Agora, isso levanta a questão ... por que chamar servo.write afetaria a qualidade da borda?
Você disse um clone. Como este?
Esses clones, em particular, tendem a se comportar de maneira irregular devido ao incrivelmente fraco desacoplamento. Deve haver capacitores de desacoplamento em cada pino de energia e o mais próximo possível do mega2560. E no arduino real, de fato existem. Nesses clones, no entanto, eles estão muito distantes, ou talvez ausentes, é difícil dizer. É óbvio, olhando para o quadro, que ele não se comportará de maneira confiável, isso é importante.
Então, qual é a diferença?
Quando você chama servo.write, ele aumenta a pilha mais do que se você chamar writeMicroseconds. Dado o ponteiro de pilha de 3 bytes do mega2560 (17 bits), é necessário inverter um monte de bits críticos que não são necessários quando se chama microssegundos de gravação. Sei que isso parece uma diferença improvável, mas experimentei meu quinhão de microcontroladores mal dissociados, e os atmegas em particular parecem exibir um comportamento estranho, especificamente ao usar temporizadores e / ou empurrar ou estourar a pilha. Algo semelhante aconteceu comigo, apenas a pilha foi corrompida quando eu estava tentando conduzir LEDs com PWM, mas se eu colocasse tudo em linha sem empurrar a pilha, funcionaria. A falta de dissociação foi o problema.
Eu esperaria plenamente que o desacoplamento ruim fosse capaz, por razões conhecidas por esse atmega2560 e mais ninguém, ter um efeito prejudicial na qualidade da borda desse pulso, mas apenas quando você estiver pressionando a pilha imediatamente antes. Esse servo não é capaz de lidar com a maneira como essas bordas estão manchadas, portanto, não vê pulsos válidos nesse caso. Outros servos obviamente conseguem.
A dissociação é sempre bizarra e hiperespecífica como esta. É por isso que a dissociação é tão importante. Mantenha os problemas de pesadelo que a falta de capacitância pode causar a você com bonés de cerâmica gordurosos e o mais próximo possível do chip, fisicamente possível.
fonte
Isso pode estar relacionado às configurações do pino de saída feitas pela rotina .write (). Tente usar um resistor pull-down de 1K, ele não funciona, remova-o e use-o resistor pull-up. isso equilibrará o efeito de qualquer resistor interno de pull-up / pull-down da semana que possa ser definido pela rotina. Quando você está medindo o sinal com seu osciloscópio, a resistência interna da sonda está atuando como um pull-down.
A maioria dos servos também libera a energia do motor interno se o sinal não estiver predefinido por 10 pulsos seguidos. Isso é usado para economizar energia.
fonte