O servo responde ao servo testador, não ao microcontrolador. Os sinais têm a mesma aparência


8

Eu tenho um servo TowerPro MG90D ( Link do fabricante ) ( Link do ServoDatabase ).
Possui uma faixa de 180 graus (não contínua).

TowerPro MG90D

Ele responde muito bem ao meu servo testador:
Servo testador

Observe o seguinte ciclo de trabalho de 7% (cerca de 90 graus) no testador:

servo testador de escopo

servo testador de escopo

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):

escopo arduino servo 90deg

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):

escopo arduino servo 1450ms

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)!

escopo arduino servo 1472ms

servo.writeMicroseconds(1550) (trabalhando):

escopo arduino servo 1550ms


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);
}

esquemático

simular este circuito - esquemático criado usando o CircuitLab


Tentei tanto uma fonte de alimentação linear de bancada, como também tentei usar um conversor buck para descer de 9V.
Bort

1
Você tem certeza de que tem uma onda constante pelos 3 segundos completos quando usa write? Não há realmente nenhuma razão para o servo não funcionar, então eu questionaria seus sinais.
Dmitry Grigoryev

1
@Ort Então estou tendo dificuldade em acreditar na sua história.
Dmitry Grigoryev

2
@ BigHomie: Os sinais são idênticos na medida em que as imagens do escopo vão. Há algo acontecendo além do sinal. Um terreno pobre é algo que pode causar reações diferentes a sinais nominalmente idênticos.
JRE

2
Se possível, capture dois traços de escopo na linha de sinal do servo com o servo conectado . Um rastreio apenas com serv1.write () e um rastreio apenas com serv1.writeMicroseconds (). Poste ambos os traços. Para um charme extra, instale um terceiro traço no testador com o servo conectado .
neonzeon

Respostas:


0

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?insira a descrição da imagem aqui

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.


0

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.


Receio que sua resposta não esteja correta. servo.write () assume um ângulo como entrada, não como tempo. As pessoas não deveriam votar nas respostas às cegas.
Bort

Sim, meu erro, não li bem o código. isso pode estar relacionado às configurações do pino de saída feitas pela rotina .write ().
555

2
Esse teria sido meu primeiro pensamento, mas os rastros de escopo parecem refutar isso. Um terreno ausente e uma situação diferente de pull / up / down podem explicar o mesmo sinal sendo enviado, mas não chegando lá (após o local da sonda).
precisa saber é o seguinte

Acho que o @KallieMP provavelmente está certo. Resistores pull-down / down podem muito bem ser a resposta. Eles podem limitar a corrente. Os pulsos podem ser formados corretamente, mas com unidade insuficiente. Portanto, não importa a função específica de servo.write (), os níveis atuais devem corresponder com precisão à saída do servo testador para obter o mesmo resultado.
SDsolar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.