El servo responde al servo tester, no al microcontrolador. Las señales se ven iguales


8

Tengo un servo TowerPro MG90D ( enlace del fabricante ) ( enlace de base de datos servo ).
Tiene un rango de 180 grados (no continuo).

TowerPro MG90D

Responde muy bien a mi servo tester:
Servo probador

Observe el siguiente ciclo de trabajo del 7% (aproximadamente 90 grados) en el probador:

alcance servo tester

alcance servo tester

Servo responde bien.


Sin embargo, cuando lo uso servo.write()con mi clon Arduino Mega 2560, el servo no responde a ningún ángulo de salida. Tengo varios otros servos que funcionan bien con el mismo código en los mismos pines.

Observe el siguiente ciclo de trabajo del 7% en el Arduino con servo.write(90):

alcance arduino servo 90deg

Ninguna respuesta. El servo es "flojo"; No tiene ninguna posición.


Mientras escribía esta pregunta, pensé en intentarlo servo.writeMicroseconds().

Aqui esta servo.writeMicroseconds(1450):

alcance servo arduino 1450ms

Servo responde!

¡Aquí está servo.writeMicroseconds(1472)(funcionando), que tiene los mismos intervalos de tiempo que el anterior no funciona servo.write(90)!

alcance servo arduino 1472ms

servo.writeMicroseconds(1550) (trabajando):

alcance arduino servo 1550ms


¿Cuál es la diferencia?
El servo tester trabajó a 49.5Hz, mientras que servo.write()falló a 49.9Hz. Me preguntaba si de alguna manera eso 0.4Hz hizo la diferencia, pero luego veo que también servo.writeMicroseconds()funcionó a 49.9Hz.

En las capturas de ámbito anteriores, se puede observar que tanto servo.write(90)y servo.writeMicroseconds(1472)tener los mismos intervalos de tiempo:
 1,474,560ns HIGH
18,544,640ns LOW

Las señales son muy similares ... ¿Qué podría causar que servo.write()no funcione?

Mi código es lo más básico posible:

#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 : esquema creado con CircuitLab


He probado una fuente de alimentación lineal de sobremesa y también he intentado usar un convertidor reductor para bajar de 9V.
Bort

1
¿Estás seguro de que tienes una onda constante durante los 3 segundos completos cuando la usas write? Realmente no hay razón para que el servo no funcione, por lo que cuestionaría sus señales.
Dmitry Grigoryev

1
@Bort Entonces me cuesta creer tu historia.
Dmitry Grigoryev

2
@BigHomie: las señales son idénticas en lo que respecta a las imágenes de alcance. Algo está sucediendo además de la señal. La mala conexión a tierra es una cosa que podría causar diferentes reacciones a señales nominalmente idénticas.
JRE

2
Si es posible, capture dos trazas de alcance en la línea de señal del servo con el servo conectado . Una traza solo con serv1.write () y una traza solo con serv1.writeMicroseconds (). Publica ambos rastros. Para un encanto adicional, agregue un tercer rastro de su probador con el servo conectado .
neonzeon

Respuestas:


0

Primero, un rápido aparte. Parece que tienes un ligero malentendido sobre cómo funcionan los servos. Los servos no están controlados por PWM, y no saben ni les importa que envíes pulsos a 49.cualquiera que sea Hz. No saben que el pulso es un porcentaje de algún período arbitrario. Al servo no podría importarle menos el tiempo entre pulsos. Digo esto porque pareces inusualmente enfocado en cosas que en realidad no importan.

Los servos ni siquiera saben ni les importa que el voltaje sea alto o bajo en un momento dado. Solo les importa una cosa: el tiempo entre un borde ascendente y un borde descendente.

El servo se controla detectando un borde de voltaje ascendente y midiendo el tiempo hasta que hay un borde descendente. Los tiempos válidos generalmente oscilan entre 1,0 y 2,0 ms, pero puede variar de servo a servo.

Puede controlarlo a 1Hz, 10Hz, 50Hz, 100Hz. La mayoría responderá a frecuencias de pulso aún más altas, pero nuevamente esto es variable. Lo que estoy tratando de decir es que la frecuencia, el ciclo de trabajo, la duración entre pulsos, todo no podría ser menos relevante para su problema, que es que el servo no responde cuando lo espera.

Lo único que es relevante son los bordes de su pulso, a los que no ha prestado atención. Si desea resolver esto, comience mirando las cosas que importan, tome capturas de cerca de los bordes de su pulso, ese tipo de cosas. No ha capturado nada útil en esas capturas de pantalla, lo que probablemente sea la razón por la que no parece haber un problema o diferencia. Hay muchos problemas o diferencias que nunca serían visibles con lo que has medido.

Lo que puedo ver es que la captura del tren de pulsos que no funciona es notablemente más sucia, tanto el pulso como el suelo, que cualquiera de los otros. Lo cual es extraño, ya que debería estar llamando a la misma función que los demás. ¿Por qué es tanto más ruidoso?

Más importante aún, en la captura no funcional, observe el 'tiempo de caída'. 809µs? Su osciloscopio cree que ve un tiempo de caída que dura 0.8 ms. Eso es malo. Claramente eso es incorrecto, pero el hecho es que eso es lo que mide.

Esa es una señal clásica de un borde sucio. Piénsalo. Si este pulso está engañando a su equipo de prueba de gama alta que es su osciloscopio para ver un borde ridículamente largo o un tiempo de caída, o tal vez tan sucio que simplemente no puede detectar correctamente el borde descendente todo el tiempo (o quién sabe), entonces ¿Qué posibilidades tiene ese pobre y asqueroso servo de $ 8 de recoger un borde decente?

Si un servo no obtiene un pulso válido (como si el flanco descendente tarda demasiado, está demasiado sucio o se pierde) dentro del rango de pulso aceptable, y por los servos que calculan los bordes que pueden o no tener algo para haz lo que consideras que son los bordes del pulso, entonces responde como si estuviera apagado.

En otras palabras, no solo no se mueve, sino que no resistirá el movimiento de su eje. Simplemente será flácido, exactamente como lo estás viendo.

Ahora, esto plantea la pregunta ... ¿por qué llamar a servo.write afectaría la calidad del borde?

Dijiste un clon. ¿Como éste?ingrese la descripción de la imagen aquí

Estos clones en particular tienden a comportarse de manera errática debido al desacoplamiento increíblemente pobre. Debe haber condensadores de desacoplamiento en cada pin de alimentación y lo más cerca posible del mega2560. Y en el arduino real, de hecho hay. Sin embargo, en estos clones, están demasiado lejos, o tal vez faltan, es difícil saberlo. Es obvio al mirar el tablero que no se comportará de manera confiable, eso es lo importante.

Entonces, ¿cuál es la diferencia?

Cuando llama a servo.write, empuja la pila más alto que si llama a writeMicroseconds. Dado el puntero de pila de 3 bytes del mega2560 (17 bits), tiene que voltear un montón de bits críticos que no tiene que hacer cuando llama a microsegundos de segundo. Sé que esto parece una diferencia poco probable, pero he experimentado mi parte justa de microcontroladores mal desacoplados, y las atmegas en particular parecen exhibir un comportamiento extraño específicamente al usar temporizadores y / o empujar o reventar la pila. Algo similar me sucedió a mí, solo la pila se corrompió cuando intentaba controlar los LED con PWM, pero si ponía todo en línea sin presionar la pila, funcionó. El desacoplamiento pobre fue, en última instancia, el problema.

Esperaría totalmente que un desacoplamiento deficiente pueda, por razones conocidas por ese atmega2560 y por nadie más, tener un efecto perjudicial en la calidad del borde de ese pulso, pero solo cuando está presionando la pila justo antes. Este servo simplemente no es capaz de manejar la forma en que se manchan esos bordes, por lo que no ve pulsos válidos en ese caso. Otros servos obviamente lo manejan.

El desacoplamiento siempre es extraño e hiperespecífico como este. Es por eso que el desacoplamiento es tan importante. Mantenga el infierno de pesadilla de problemas, la falta de capacitancia puede causarle problemas con gorros de cerámica gruesos y tan cerca del chip como sea físicamente posible.


0

Esto puede estar relacionado con la configuración del pin de salida realizada por la rutina .write (). Intente usar una resistencia pull-down de 1K, si no funciona, luego retírela y úsela. esto equilibrará el efecto de cualquier resistencia interna pull-up / pull-down de semana que pueda establecer la rutina. Cuando está midiendo la señal con su osciloscopio, la resistencia interna de la sonda actúa como un pull-down.
La mayoría de los servos también liberarán la energía al motor interno si la señal no está preajustada para 10 pulsos seguidos. Esto se usa para ahorrar energía.


Me temo que su respuesta no es correcta. servo.write () toma un ángulo como entrada, no como tiempo. La gente no debería votar a ciegas las respuestas.
Bort

Sí, mi error, no leí bien el código. Esto puede estar relacionado con la configuración del pin de salida realizada por la rutina .write ().
555

2
Este habría sido mi primer pensamiento, aunque las huellas de alcance parecen refutar esto. Una tierra faltante y una situación diferente de pull-up /-down podrían explicar la misma señal que se envía pero no llega allí (después de la ubicación de la sonda).
KalleMP

Creo que @KallieMP probablemente tenga razón. Las resistencias pullup / down bien podrían ser la respuesta. Podrían limitar la corriente. Los pulsos pueden formarse correctamente pero sin suficiente impulso. Entonces, sin importar la función particular de servo.write (), los niveles de corriente deben coincidir con precisión con la salida del servo tester para obtener el mismo resultado.
SDsolar
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.