Conteo de pulsos con Arduino

La respuesta del motor no será muy lineal, tendrá una histéresis importante, muy importante probablemente.
Osea que si queremos moverlo poco no se moverá. Porque el error de posición es mínimo y al multiplicar por kp da una tensión que no es capaz de mover nada.
Puede ser...pero sin análisis completo del motor no podemos saberlo. Si el mínimo de un PWM de 15 trae problemas, aumentamos la KP o agregamos una parte integral y listo. El problema es que ambos pueden inestabilizar el lazo y es mejor ir por el lado mas seguro sin parte integral.

De todas formas vos proponés un control tabulado, lo cual es mas complicado que el proporcional para definir la tabla posición vs velocidad...y lo mismo debe operar en lazo cerrado.
La pregunta es que pasa si solo lo quieres mover un saldo de imán. ¿Cuánto vale kp?
Antes de eso hay que preguntar: cual es la reducción de la caja asociada a ese motor???
 
Ya puestos ... ¿Y frenar el motor?
Cortocircuitar sus bornes con un transistor.... ¿O eso ya lo hace el diodo volante? ¿En qué sentido va la fcem? (Me parece que sí que se lo come el diodo)
 
El diodo no se puede poner al revés porque el motor no iría y se quemaría el transistor.
El diodo se come los pulsos de energía que devuelve la bobina al cortar la corriente.
Lo que no tengo claro es el sentido de la fuerza contraelectromotriz que genera el motor al actuar de generador. Debería de ser contraria a cómo va cuando actúa de motor y por lo tanto ya la absorbe el diodo.
 
Lo que no tengo claro es el sentido de la fuerza contraelectromotriz que genera el motor al actuar de generador
El diodo se "come" los pulsos inversos que se generan cuando el pulso del PWM cae a cero, en ese caso la inductancia se opone a la caída y larga "un zapatazo hacia arriba" (opuesto a la caída a 0) que excede el valor de Vcc y el diodo la recorta a 0.7V.
Ver ondas en este hilo: Eliminando ruidos durante el apagado de equipos de audio ... no es sobre motores pero el efecto de las inductancias es el mismo.
Ya puestos ... ¿Y frenar el motor?
El problema es que seguimos en lazo abierto y tendriamos que jugar con el tiempo necesario antes de frenarlo para que termine donde debe.
Dos preguntas:
1-Cual es la reduccion del sistema??
2- A que velocidad debe girar el coso ese que se cuelga al otro extremo del reductor???

Pasen una especificacion tecnica, please!!!!
 
Última edición:
No tengo especificaciones técnicas del motor, ademas de eso deberia poder conectarle cualquier actuador comercial que compre en un futuro.
Aca te dejo la poca informacion de un actuador de marca superjack (es el otro que tengo, el que zumba un poquito con el PWM):
Specifications:
  • Model: Super jack QARL series
  • Motor: DC brush motor
  • Input: 24/ 36V DC
  • Load Capacity: 3000N
  • Standard Stroke Length: 450mm/ 600mm/ 900mm
  • Drive Screw: ACME
  • Full Load Speed: 5 mm/sec
  • Duty Cycle: 20%
  • Temperature: -26˚C to 65˚C (-15˚F TO 150˚F)
  • Limit Switch: Adjustable
  • Sensor: Reed switch sensor
  • Static Load: 4500N
  • Duty Cycle: 10%

El FTA es otro de mis hobbys por eso estoy haciendo el posicionador y la idea despues de terminarlo es hacer la documentacion necesaria y publicar el proyecto completo para el que quiera construirlo.

Ahora cambie los componentes como me recomendaron:
Resistencia de pull-up = 10k
Cambie la resistencia del gate del mosfet por una de 10k a GND
Puse una resistencia de 10 ohm en serie al gate. (a maxima velocidad con el PWM tengo 11.53v en el gate)
Quite el capacitor del pull-up

Ahora el motor ya no se mueve con el PWM en 15 con ese valor mido unos 5-6vcc, el valor maximo con el que se posiciona bien es de 80.
Si muevo siempre a la maxima velocidad igualmente se pasa 2 o 3 pulsos mas/menos.
Con el PWM bajando la velocidad unos 50 pulsos antes de llegar al destino se esta posicionando bien sobre los satelites y no tengo mal conteo de pulsos.

Intentare implementar lo que comenta Dr.Zoidberg y posteo lo que salga.

Conseguí 1 sensor hall, 1 CNY70 y un reed switch nuevo para hacer pruebas, principalmente el sensor hall porque ya hay actuadores con esos sensores asi veo como adapto el circuito.

edit:
Probe esto dentro de loop():
Código:
errpos = abs(motor2PulsosDestino - motor2PulsosActuales); //obtengo la diferencia sin signo
    accionControl = 4 * errpos;
    PWM = (int)accionControl; 
    if (PWM > 255) {
        PWM = 255;
    }
    
    if (PWM < 50) { //50 es lo minimo con que se mueve el motor a maxima carga
        PWM = 50;
    }

El efecto que causa es que el motor baja la velocidad progresivamente hasta el valor minimo.
Se posiciona igual de bien que bajar la velocidad al minimo de forma subita
 
Última edición:
No es buena idea poner a C4 por que afecta el cierre y la apertura del reed-switch, y por ende el "pulso" generado.
Si tenés un problema con el relay, buscalo y solucionalo, pero no desparramés capacitores al voleo y menos en ese lugar.

El otro problema es el cambio de sentido de giro con un relay en lugar de usar en puente H, pero bueno...veremos como vá.
Vas a tener que hacer algo PARECIDO a esto:

C-like:
/* OJO!! ESTO NO NECESARIAMENTE DEBE FUNCIONAR - ES PARA MOSTRAR LA IDEA */
#define DERECHA 1
#define IZQUIERDA 0
...
...
...

errPos = posDeseada - posActual;

/* Calculamos la accion de control proporcional */
accionDeControl = KP * errPos;

/* Ajustamos magnitud y signo del PWM --> supongo que es de 8 bits */
if( accionDeControl < 0) {
        accionDeControl = -accionDeControl; /* la magnitud del PWM siempre es >0 */
        digitalWriteFast( SENTIDO_DE_GIRO, IZQUIERDA );
} else {
    digitalWriteFast( SENTIDO_DE_GIRO, DERECHA );
}
if( accionDeControl > 255) {
        accionDeControl = 255; /* ese es el valor limite de un PWM de 8 bits */
}
/* y sacamos por el pin de PWM */
analogWrite( pinPWM, accionDeControl );



...
/* ESTO SOLO ES PARA MOSTRAR LA IDEA!! - No funciona tal como esta!! */
/* y en la rutina de interrupcion del timer que fija el tiempo de muestreo */
cuentaActual = TCNT1;    /* supongamos que leemos el Timer 1 */
delta = ultimaCuenta - cuentaActual;    /* OJO con el valor de delta!!! el Timer a usar "deberia ser" up-down pero hay que inventar otra cosa */
posActual += delta;
 
Última edición:
El sentido de giro yo lo tenia resuelto de otra forma, por ejemplo mover la parabolica hacia el este

C-like:
void  moverMotor2Este() {
    //Si el motor no esta en el limite minimo
    if (motor2PulsosActuales > motor2LimiteEste) {
        pararConteoPulsos = false; //no parar conteo de pulsos
        //actualizarLCD = true; //actualizar pantalla
        //Parar los motores si se estan moviendo
        pararMotorEsperar //parar el motor y esperar para mover
        //Parar interrupciones, para evitar posibles pulsos erroneos por ruido inducido por el relee
        detachInterrupt(digitalPinToInterrupt(sensor2));
        motor2Referencia = false; //no vamos a referencia
        motor2Este //primero cambia sentido giro
        delay(100); //espero que se estabilice el relee
        //habilitar interrupciones
        attachInterrupt(digitalPinToInterrupt(sensor2), restarPulsosM2, modoConteoPulsosM2);
        pwmMotor2Antes = pwmMotor2; //valor actual = 0
        
        //dependiendo de la cantidad de pulsos a mover la velocidad INICIAL
        if ((motor2PulsosActuales - motor2PulsosDestino) > pulsosBajarVelocidad) { //mas de x pulsos,rapido
            pwmMotor2 = motor2Rapido;
        }
        else {
            pwmMotor2 = motor2Lento;
        }
    }
    else { //limite
        escribirLCD(F("Motor 2: limit"));
        tonoLimites();
    }
}

Y una vez que se esta moviendo, dentro del loop actua el control proporcional

Esto seria para que se ejecute cada X ms usando el timer?
C-like:
/* ESTO SOLO ES PARA MOSTRAR LA IDEA!! - No funciona tal como esta!! */
/* y en la rutina de interrupcion del timer que fija el tiempo de muestreo */
cuentaActual = TCNT1;    /* supongamos que leemos el Timer 1 */
delta = ultimaCuenta - cuentaActual;    /* OJO con el valor de delta!!! el Timer a usar "deberia ser" up-down pero hay que inventar otra cosa */
posActual += delta;
 
No, eso pretende ser un ejemplo incompleto de como leer el conteo de un timer y actualizar la posicion recorrida.
Ok, eso seria lo que ahora mismo hago con las interrupciones.

Parabolica posicionandose bajando la velocidad abruptamente al valor minimo:

Parabolica posicionandose con el control progresivo:

Como ven todavía falta ajustar un poco la variable KP

Cualquiera de las 2 formas funcionan bien, me voy a quedar con el control progresivo.
Quite C4 del circuito, ahora no tengo anti-rebote por hardware.
Debería implementarlo por software como lo tenia antes por las dudas?, algo de 1 o 2 ms quizás ?

En estos días le adapto el sensor hall y les comento los resultados que me de.
El sensor hall lo alimento con 12 Vcc, GND y la salida la puedo conectar directo al optoacoplador o debería colocarle un transistor?.
Porque segun el datasheet la salida solo soporta hasta 25ma y anda por ahí el consumo del opto + resistencia en paralelo.

Edit: la variable KP, en el menu de configuracion la podriamos llamar "distancia de parada" o como seria un nombre mas adecuado?
 
Última edición:
Para eso mejor progresivo el arranque y la parada. Los engranajes sufrirán menos.
Por otro lado has visto que pasa si empujas con la mano ¿Se mueve la reducción?
Lo digo porque habrá que ver qué pasa con viento.


Que yo sepa esos hall van de 3 a 30V, más o menos. Hablo de memoria . Así que como quieras.
Lo mismo el hall va sin optoacoplador.
 
la variable KP, en el menu de configuracion la podriamos llamar "distancia de parada" o como seria un nombre mas adecuado?
KP se llama "ganancia proporcional" y no se si debería ser facilmente accesible por que si la cambia alguien que no sabe, puede inestabilizar el lazo y hacer que la antena quede oscilando en lugar de detenerse...o peor aun...
Para eso mejor progresivo el arranque y la parada.
No es imprescindible un arranque suave por que la velocidad de movimiento es proporcional a la distancia a recorrer, asi que solo viaja al maximo cuando la distancia es grande.
Para un arranque suave hace falta agregar un control de velocidad y/o un planificador de trayectoria...y en esta etapa me parece demasiado...
 
Para eso mejor progresivo el arranque y la parada. Los engranajes sufrirán menos.
Por otro lado has visto que pasa si empujas con la mano ¿Se mueve la reducción?
Lo digo porque habrá que ver qué pasa con viento.

La reducción no se mueve,los imanes tampoco, dentro del motor esta todo muy bien mecanizado.
Lo que si se mueve un poquito es la parabólica, pero es por la forma en que se acopla con el actuador
es un eje sin fin con un engranaje grande
Top2.JPG

Lo mismo el hall va sin optoacoplador.
Te refieres a que debo conectarlo directo sin opto o que funciona igual sin opto?.
Si no le pongo el opto, no se meteria ruido por el cable al usar el sensor hall?

KP se llama "ganancia proporcional" y no se si debería ser facilmente accesible por que si la cambia alguien que no sabe, puede inestabilizar el lazo y hacer que la antena quede oscilando en lugar de detenerse...o peor aun...

Pero por ejemplo si cambio de actuador posiblemente tenga que ajustar el valor de la variable?.
Por ejemplo los valores maximos y minimos del PWM deberian ser configurables, ya comprobe que el otro actuador reacciona diferente a este.
 
Debería implementarlo por software como lo tenia antes por las dudas?, algo de 1 o 2 ms quizás ?
Por soft es mas facil, por que solo tenes que encontrar la diferencia de tiempo (en conteo de un timer?) entre dos lecturas sucesivas y descartar la interrupción si esta diferencia es inferior al período minimo de la señal de entrada esperada (20 Hz --> 50 ms).
Pero por ejemplo si cambio de actuador posiblemente tenga que ajustar el valor de la variable?.
Por ejemplo los valores maximos y minimos del PWM deberian ser configurables, ya comprobe que el otro actuador reacciona diferente a este.
Seguro que para otro actuador hay que cambiar los parametros, pero si vas a permitir que todo sea configurable deberias advertir los riesgos.
 
Por soft es mas facil, por que solo tenes que encontrar la diferencia de tiempo (en conteo de un timer?) entre dos lecturas sucesivas y descartar la interrupción si esta diferencia es inferior al período minimo de la señal de entrada esperada (20 Hz --> 50 ms).
Lo que hacia era esto dentro de la interrupción:
Código:
m2PulsoAhora = micros(); //tiempo actual
    if ((m2PulsoAhora - motor2UltimoPulso) > tiempoAntiReboteMotor2) { //tiempo anti-rebote
        motor2UltimoPulso = m2PulsoAhora; //almaceno el tiempo actual
        motor2PulsosActuales++; //suma 1
        if ((motor2PulsosActuales >= motor2PulsosDestino) || (motor2PulsosActuales >= motor2LimiteOeste)) {
            pararMotor2();
        }
    }

Incluso podría hacer una función de "auto ajuste" que me de el valor necesario para el anti-rebote.
Seria medir el periodo durante todo el recorrido o por lo menos donde el recorrido es mas rápido, obtener la media y quizás ajustarlo un poquito para abajo.
 
Última edición:
Si haces un control proporcional con kp y luego satura y tiene un mínimo entonces estamos en una simple parada suave. Se arranca al 100% y por decir algo 50 pulsos antes se baja un 1% cada pulso hasta llegar al 50 (también por decir algo) que es donde el motor se para y es el mínimo con el que el motor se mueve.
Si saturados por arriba y por abajo de control proporcional tiene poco, el nombre y poco mas.
Por otra parte hacer un arranque suave me parece interesante para no dañar la piñonería. Y un control proporcional, o pid puro no lo hará.
Yo haría eso, una aceleración y deceleración en rampa y el resto al 100%.
La rampa estaría mejor por tiempo que por pulsos, si normalmente arranca al 50 , al primer pulso pasa al 51 etc, si un día por lo que sea no arranca se quedará ahí, porque con 50 no mueve y no llega al 51. Si es por tiempo pasará al 51 52... Hasta que empiece a mover.
Eso le pasaría también al control P
Un PI sin embargo acumulativa error I con el tiempo lo que al final daría más salida y lo haría arrancar.
Acabo de ver que la reducción es un sinfín. Eso evita que el viento la nueva, aunque el viento puede hacer que cuate más o menos de mover.
 
Última edición:
podría hacer una función de "auto ajuste" que me de el valor necesario para el anti-rebote.
Seria medir el periodo durante todo el recorrido o por lo menos donde el recorrido es mas rápido, obtener la media y quizás ajustarlo un poquito para abajo.
Yo no me complicaria tanto!!!!
Si vos esperas una frecuencia de conteo maxima de 20Hz, ninguna interrupcion puede ocurrir a menos de 50 ms de la anterior, asi que se descarta y no se hace nada. Si cambias esr minimo cambias la frecuencia estimada de entrada y no te metes en algoritmos adaptivos.

Si saturados por arriba y por abajo de control proporcional tiene poco, el nombre y poco mas.
La saturacion siempre ocurre en un controlador real por que un actuador no puede entregar energia ilimitada, aunque trabajemos en punto flotante.
Se puede mapear la accion de control a una saturacion mas elaborada que el if que puse, pero como el PWM tiene resolucion y limite acotados, pues no queda otra que saturar...
 
Ok.
intentare implementar un arranque suave.

Yo no me complicaria tanto!!!!
Si vos esperas una frecuencia de conteo maxima de 20Hz, ninguna interrupcion puede ocurrir a menos de 50 ms de la anterior, asi que se descarta y no se hace nada. Si cambias esr minimo cambias la frecuencia estimada de entrada y no te metes en algoritmos adaptivos.

Con eso solo me referia a una opcion mas en la parte de configuracion, que muestre por la LCD la frecuencia y el periodo de cada pulso.
me parece que seria una ayuda extra para ponerlo en funcionamiento.

Me gusto lo de "parada suave" para setear "visualmente" la variable KP, lo que sucede si le pongo un valor bajo es que la mayor parte del recorrido lo hace a mínima velocidad, pero con un valor mas alto la disminución de velocidad es mas progresiva.
 
lo que sucede si le pongo un valor bajo es que la mayor parte del recorrido lo hace a mínima velocidad, pero con un valor mas alto la disminución de velocidad es mas progresiva.
Es logico que asi suceda ya que el valor del PWM es el error de posicion x KP y si KP es pequeña tambien lo será la velocidad maxima.


intentare implementar un arranque suave
Una vez ajustado el controlador, en lugar de entregarle la posicion final, dividís la diferencia entre la final y la actual en un cierto numero de pasos, ponele 20, donde los 5 primeros y los 5 ultimos son mas pequeños que los 10 del medio.
Entregando esos valores al ritmo adecuado estaras generando una rampa de velocidad de arranque y otra rampa de velocidad de frenado, siendo los del medio a velocidad constante.
 
Atrás
Arriba