Conteo de pulsos con Arduino

No exageremos, son 16 bytes, si no te gusta 9600 o es lento, lo pones a 19k2, hay mucho trecho antes de 115k2.
A eso voy!!
 
No sé qué pasa si recibes más de 32 caracteres, supongo que se pierden. Esa prueba no la he hecho.
Para mi gusto va un tanto corto el buffer, los que yo he programado han sido de 256 o 128 bytes, para tener punteros cortos pero de un tamaño razonable.

Bueno, si no tiene problemas en la transmisión, por ruidos en el cable etc cuanto más rápido mejor.
¿Que gana tardando más?

A lo mejor la interrupción del Arduino es una basura, no sé cómo está hecha, las que yo hice eran como cuatro o cinco instrucciones CM.
Mover byte
Aumentar puntero
Activar algún flag
Retorno de interrupción

Algo así más o menos, eso es menos de 1uS a 16MHz,
 
Bueno.
Hice lo siguiente:
Código:
logLinea(micros());
noInterrupts();
tmp2 = motor2PulsosActuales;
interrupts();
logLinea(micros());
No pude usar ATOMIC BLOCK porque no compilaba.
El resultado es que demora en promedio unos 400us, a veces un poquito mas y a veces un poquito menos.
No creo que tenga problemas, ademas estuve leyendo que si paro las interrupciones y justo recibo una, esa no se pierde.
Y actualmente recibo una interrupción cada 75ms aproximadamente.

Les pido discupas porque cometi un error, la comunicacion serial con la PC la tengo a 115200 baudios, esa la voy a usar para setear los nombres de los satelites asi aparecen en la LCD pero no se va a usar mientras el motor se mueva, es mas va a estar desactivada y la activo dentro del menu con la botonera cuando sea necesario.
La comunicacion con el PIC que es de donde recibo los 16 caracteres la tengo a 19200 baudios.

Hice este menu que me muestra la frecuencia de los pulsos que recibo (coinciden con las mediciones del tester, es lo que tengo para medir).
Ademas veo la salida del PWM y el intervalo de pulsos en ms (con eso puedo configurar el tiempo de espera para recibir 1 pulso).
En debounce muestra el valor mas bajo de intervalo que registro, de esa forma tengo un valor de referencia para configurar el anti-rebote. (no lo necesito con el hall, pero lo voy a dejar porque anda bien).

Volviendo al tema de los imanes, la separación ideal que deben de tener esta relacionada a la reducción de los engranajes?.
Porque si los pongo muy cerca uno de otro volvería a tener el problema de que cuando se pare el motor por la misma inercia se mueva hasta el siguiente imán.
Aun no saque el motor, pero a ojo creo que el engranaje donde están los imanes tiene unos 4 cm de diametro, podria ponerle unos 12 imanes cada 1 cm aproximadamente.
 
Aca les dejo los datos de los engranajes.
El blanco es el que se engancha con el eje sin fin que mueve la antena.

Los imanes que compre son de 3mm de diametro
 

Adjuntos

  • IMG_20190831_145102.jpg
    IMG_20190831_145102.jpg
    408.8 KB · Visitas: 5
  • IMG_20190831_145112.jpg
    IMG_20190831_145112.jpg
    280.5 KB · Visitas: 5
Estuve haciendo pruebas con esos imanes y voy a tener que conseguir otros mas potentes y quizás de 6 mm
Tienen que estar a unos 2 o 3 mm del sensor para funcionar y perfectamente alineados, va a ser muy difícil que pueda hacer los agujeros manualmente tan perfectos.
 
Al final use los imanes de 3mm.
No quedaron perfectamente alineados pero funciona bien.
La frecuencia de los pulsos varía entre 58 y 60 Hz dependiendo de la velocidad.
También tuve que reducir el PWM porqué seguia unos pulsos de largo
 
Les consulto esto acá para no abrir otro tema.
Estoy usando el puerto serial 2 del arduino para leer los datos que me envia un PIC dentro del loop().
supongamos que al pic siempre le envio estos datos:
E0 10 39 F5
En el arduino recibo esto:
E0 10 39 F5
Pero si entro en un while o cualquier otro "codigo bloqueante" cuando salgo y vuelvo al loop()
en el serial leo esto:
E0 10 E0 10 39 F5

Es posible que mientras estoy ocupado dentro del "codigo bloqueante" el buffer el puerto serial se va llenando y por eso tengo esa salida?
Lo que hice fue poner un if para procesar el comando solo si la longitud es valida.
Alguna otra solucion mas "elegante"?, tengo que limpiar el buffer del serial?
El while por ejemplo lo uso en los menu de configuracion:
JavaScript:
void subMenuPantalla() {
    actualizarLCD = true;
    boolean salirSubMenu = false;

    //TIEMPO DE REFRESCO
    lcd.clear();
    lcd.print(F("Screen setting"));
    lcd.setCursor(0, 1);
    lcd.print(F("refresh time (ms):"));
    lcd.setCursor(0, 3);
    lcd.print(F("f1:exit"));
    lcd.setCursor(13, 3);
    lcd.print(F("f2:save"));

    while (salirSubMenu == false) {
        if (actualizarLCD == true) {
            actualizarLCD = false;
            lcd.setCursor(0, 2);
            lcd.print(String(tiempoRefrescoLCD / 1000) + " ");
        }

        //lectura de botones
        btnEste.read();
        btnOeste.read();
        btnF1.read();
        btnF2.read();

        //si se pulsa f1, se sale
        if (btnF1.wasPressed()) {
            salirMenu = true;
            mostrarMenu();
            break;
        }

        //si se presiona este, aumenta 100ms
        if (btnEste.isPressed()) {
            if (tiempoRefrescoLCD < 1000000UL) {
                tiempoRefrescoLCD = tiempoRefrescoLCD + 100000UL;
                actualizarLCD = true;
            }
        }

        //si se presiona oeste, disminuye 100ms
        if (btnOeste.isPressed()) {
            if (tiempoRefrescoLCD > 100000UL) {
                tiempoRefrescoLCD = tiempoRefrescoLCD - 100000UL;
                actualizarLCD = true;
            }
        }

        //si se prsiona f2, guarda los cambios
        if (btnF2.wasPressed()) {
            guardarConfig();
            lcd.clear();
            lcd.print(F("Config saved"));
            delay(1000);
            salirSubMenu = true;
            actualizarLCD = true;
            break;
        }

        //anti rebote botonera
        delay(100);
    }
}

Lo del conteo de pulsos quedo funcionando perfecto.
Gracias.
 
El buffer del Arduino tiene 32 bytes de entrada y 32 de salida , a priori no deberías de perder nada...

Por otro lado tú mismo te has contestado para este u otros casos. No programes nada con "códigos bloqueantes" que ya ves lo que pasa.
 
El buffer del Arduino tiene 32 bytes de entrada y 32 de salida , a priori no deberías de perder nada...

Por otro lado tú mismo te has contestado para este u otros casos. No programes nada con "códigos bloqueantes" que ya ves lo que pasa.
Me acabo de dar cuenta de que la explicación del buffer fifo del Arduino ya estaba en este mismo hilo, y más amplia... Osea que el "código bloqueante" debe de ser de marca, lo mismo inhibe interrupciones y se queda en un while.
 
Hola.
Sigo con el desarrollo del posicionador, por ahora todas las mejoras que me recomendaron dieron resultado y funciona bien con los actuadores que tengo.
Pero estos dias probe un actuador que se comporta un poco extraño.
Con un duty de 50 por ejemplo que es a la velocidad donde se mueve pulso a pulso.
Haciendo su maximo esfuerzo (completamente retraido, tocando el limite mecanico) al subir cuenta los pulsos de 1 en 1 pero en realidad el movimiento de la parabolica es minimo.
Entonces al moverlo un poco mas arriba, quizas 3/4 del recorrido ya empieza a funcionar bien, pero queda todo el conteo de pulsos errado.
Pense que el problema es por la frecuencia del PWM que estaba en 490hz como es por defecto el arduino, intente subirla y bajarla un poco pero no dio mucho resultado.

Si los movimientos se hacen siempre a maxima velocidad o con un duty de 180 por ejemplo, no presenta ese problema, aunque obviamente a esa velocidad se para 2 o 3 pulsos de mas.

Encontre una libreria que permite de manera muy facil alterar la frecuencia de los timers.

Yo use de esta forma la libreria para alterar la frecuencia del Timer1 que afecta a los pines 11 y 12 donde tengo conectado los motores en el arduino mega.

Código:
Timer1_Initialize();
//el timer 1 afecta al PWM de los pines 11 y 12
Timer1_SetFrequency(1200); //frecuencia en HZ

Serial.println(F("frecuencia timer1:")); //deberia de estar a la frecuencia configurada
Serial.println(Timer1_GetFrequency());
Serial.println(Timer1_GetResolution());

Para accionar el PWM no me funciono bien con analogWrite asi que uso:

Código:
pwmWrite(uint8_t pin, uint8_t duty) 8-bit, 0 - 255
pwmWriteHR(uint8_t pin, uint16_t duty) 16-bit, 0 - 65535

Medicion de frecuencia con los valores por defecto del timer
arduino defecto.jpg

Configurado en 1200hz
1200hz.jpg

Yo creo que tomando en cuenta la precision del tester la frecuencia esta bien

Aca mas informacion sobre la libreria
 

Adjuntos

  • PWM.zip
    11.2 KB · Visitas: 1
Me huele a problema mecánico.
Según cómo esté el actuador, es probable que necesites más par en ciertas zonas... Tendrías que hacer una curva de duttys según en qué momento se encuentre el posicionador.
Por ejemplo, suponiendo un actuador en el que el par pasa uniforme, cuando el telescopio está horizontal, si no está contrapesado necesitas mucho más par que cuando está casi vertical, que sería casi cero. Si el actuador es lineal y hace palanca la curva del par necesario no es en absoluto lineal.

En principio, la frecuencia no influye en absoluto en el resultado.

¿En esa zona funciona bien al revés? Es decir, "bajando" en lugar de "subiendo"
 
Me huele a problema mecánico.
Según cómo esté el actuador, es probable que necesites más par en ciertas zonas... Tendrías que hacer una curva de duttys según en qué momento se encuentre el posicionador.
Por ejemplo, suponiendo un actuador en el que el par pasa uniforme, cuando el telescopio está horizontal, si no está contrapesado necesitas mucho más par que cuando está casi vertical, que sería casi cero. Si el actuador es lineal y hace palanca la curva del par necesario no es en absoluto lineal.

En principio, la frecuencia no influye en absoluto en el resultado.

¿En esa zona funciona bien al revés? Es decir, "bajando" en lugar de "subiendo"

Había pensado hacer que estando sobre los limites el duty aumente, aunque no tenga una precisión pulso a pulso.
Hace lo mismo yendo de Este a Oeste o yendo de Oeste a Este.

Entonces hacer que la frecuencia del PWM sea configurable no aporta nada cierto?.
 
Vale, pensaba que era subiendo y bajando.
En principio necesitas otro actuador...o

Para que mueva das pongamos el 50% durante un corto periodo y después bajas.
En su día lo hice con un ventilador, aunque es un problema más sencillo.
Podía ir pongamos al 20, al 50 y al 100% al 20 no arrancaba pero si que mantenía si ya estaba en movimiento. Si empezabas de parado poniendo el 20 lo que hacía el sistema era poner el 50 durante 1/10" y después el 20, así arrancaba y luego se mantenía. A ojos del usuario arrancaba al 20, porque así sería, con el 50 empezaba a acelerar y antes de llegar a la velocidad entraba el 20.
 
Vale, pensaba que era subiendo y bajando.
En principio necesitas otro actuador...o
.
Por las dudas aclaro nuevamente porque no entendí.

El problema solo se presenta al hacer movimientos pulsados con un duty de bajo valor (por ejemplo, presiono el boton para mover al este cada 1 segundo), siempre y cuando el actuador este sobre sus extremos (tiene que hacer un mayor esfuerzo para moverse).

El posicionador cuenta los pulsos normalmente pero se nota que la parabolica se mueve muy poquito entonces al enviarlo a una posicion previamente almacenada, no se posiciona bien porque el conteo de pulsos quedo todo errado, es como si hubiese contado pulsos que no existen.

Pero si hago un movimiento continuo con un duty de bajo valor, funciona perfectamente.

Por ahora probe con 3 actuadores y solo uno tiene este problema.
Ya no voy a poder probar mucho mas con este posicionador porque tengo que devolverlo, pero por lo menos puse una opción para que el movimiento pulsado sea con duty maximo o minimo.
Mi idea era probar con todo lo que pueda para asegurarme de que el proyecto funciona y no subir cualquier cosa que le haga perder tiempo y dinero a las personas que quieran construirlo.
 
Me huele a que estás usando un actuador lineal para un movimiento circular y claro, tienes los puntos muertos inherentes del mecanismo biela-manivela, en su proximidad el actuador lo llevará mal tirando a muy mal.
Si el actuador es circular no debería de pasar eso. Bueno... quizás sí porque el peso del telescopio se "descuelga" en ciertos ángulos. No sé, habría que ver el mecanismo, algo de eso creo que es.
 

Asi va montado el actuador en la parabolica, este actuador funciona bien es un superjack de 24 pulgadas.
El que probe con malos resultados es similar pero no se marca ni modelo porque ya no la tenia.
este lo tengo funcionando con reed switch y el otro que mostre anteriormente fue al que le cambie el sensor por uno hall.
 
Pues estás muy lejos del punto muerto según se ve. En cualquier caso ese montaje no da una relación lineal actuador-ángulo dará la ecuación de una catenaria o algo así.
Se me ocurren varias cosas.
Cambiar el actuador
Hacer un control "dinámico" como el que he contado que para que arranque le pongas más dutty un segundo, o el tiempo adecuado y luego bajes
Poner un freno eléctrico para que pare antes cuando estás usando duttys altos, eso se conseguiría cortocircuitando los bornes del motor cuando se desconecta., Con un pin del Arduino mandas el pwm y con otro cortocircuitas los bornes inmediatamente después de parar el pwm.


O una mezcla de todo eso
 
Pues estás muy lejos del punto muerto según se ve. En cualquier caso ese montaje no da una relación lineal actuador-ángulo dará la ecuación de una catenaria o algo así.
Se me ocurren varias cosas.
Cambiar el actuador
Hacer un control "dinámico" como el que he contado que para que arranque le pongas más dutty un segundo, o el tiempo adecuado y luego bajes
Poner un freno eléctrico para que pare antes cuando estás usando duttys altos, eso se conseguiría cortocircuitando los bornes del motor cuando se desconecta., Con un pin del Arduino mandas el pwm y con otro cortocircuitas los bornes inmediatamente después de parar el pwm.


O una mezcla de todo eso

Ok, voy a seguir probando mas actuadores a ver si sucede lo mismo con otro e intentare hacer el control dinámico.
Como ven en ese video pude hacer que inicie el movimiento progresivamente, comienza de 0 hasta tomar el valor del control proporcional aumentando el duty de 3 en 3 (solamente cuando el movimiento es continuo, si es pulsado solo se mueve a la maxima o minima velocidad).

Hoy aproveche para ver como estaba internamente el motor del primer actuador que mencione en este tema, el que le cambie el sensor por uno hall y los imanes (la parabolica negra que se ve en los videos).
Ese actuador (y toda la parabolica) debe de tener por lo menos 30 años. La adquiri en mal estado y la restaure.
El motor lo lleve a reparar y me lo dieron funcionando.
Pero vi que los carbones están un poco feos y como que se desgranaron un poco.
Al usar el PWM se desgastan mas seguido?, puedo comprar cualquier carbón que tenga las medidas iguales y colocarlo o vienen indicados para diferente tensión/amperaje/uso ?.
Me parece que son los carbones originales y no fueron reemplazados. porque el conector de los cables tiene un aspecto bastante "viejo".
Dejo algunas imágenes:
IMG_20191027_124412.jpgIMG_20191027_130907.jpgIMG_20191027_132011.jpgIMG_20191027_132027.jpgIMG_20191027_132101.jpg

Al colector le pase una lija 400 para limpiarlo y limpie entre las delgas.
 
Atrás
Arriba