Conteo de pulsos con Arduino

#1
Hola.
Estoy haciendo un posicionador con un arduino mega para un motor que tiene un reedswicth para contar pulsos.
El codigo y el circuito funcionan relativamente bien, tengo un pullup y un anti-rebote por software de unos 5 ms.

Mi duda es si con un tester que tiene funcion para medir frecuencia (kyoritsu 1009) puedo saber cuantos "pulsos" por segundo da el motor.
Este es el diagrama que estoy usando:
Captura.PNG

El tester lo conecte donde dice "tester+" y "tester-", cuando el motor gira da una lectura entre 9 y 11 hz, esto puede ser correcto?.

El arduino mega es capaz de contar a esa velocidad usando las interrupciones? (entiendo que serian entre 9 y 11 "pulsos" por segundo)

Otra consulta, las resistencias R2 y R3 las coloque en serie como para "filtrar" algun tipo de interferencia, esto tiene sentido?

Aca estan las especificaciones del tester:
Captura.PNG
Saludos.
Olvide menciona la distancia aproximada del reed switch y el arduino son 30 metros
 
#2
No entiendo ese circuito te va a dar positivo y positivo. No veo por qué te va a dar negativo en ningún caso.
Así que o se me está escapando algo o eso no va a funcionar.

Un Arduino puede medir fácilmente algunas decenas de kHz si no haces tonterías. Si llenas tu código de delays y cosas así puede que no mida nada.
 
#3
No entiendo ese circuito te va a dar positivo y positivo. No veo por qué te va a dar negativo en ningún caso.
Así que o se me está escapando algo o eso no va a funcionar.

Un Arduino puede medir fácilmente algunas decenas de kHz si no haces tonterías. Si llenas tu código de delays y cosas así puede que no mida nada.
Dibuje mal el circuito :facepalm:
Captura.PNG

Ahi lo arregle, crees que la forma de medir la cantidad de pulsos con el tester es correcta?.
Gracias.
 
#4
Yo es que soy espartano mi circuito es ∅ hasta que veo que no funciona y le pongo cosas.

Pulsador entre el pin y gnd y activada la R interna de pullup. Ya está. 0€.

Si no va ya veremos por qué y qué hay que hacer.
 
#5
Yo es que soy espartano mi circuito es ∅ hasta que veo que no funciona y le pongo cosas.

Pulsador entre el pin y gnd y activada la R interna de pullup. Ya está. 0€.

Si no va ya veremos por qué y qué hay que hacer.
El circuito funciona y el codigo tambien, ya pase por las etapas de pruebas con el pullup y el interno no me fue util con el cableado largo. en este caso no me interesa si el costo aumenta por poner unos pocos componentes.

Solo queria saber 3 cosas:
Si arduino puede contar mas de 20 pulsaciones por segundo -> ya me lo aclaraste
Si la inclusion de R2 y R3 cumple una funcion positiva para filtrar el ruido que ingresa por los cables del sensor (esta a 30 metros)
Si la forma en que medi "la cantidad de pulsos" con el multimetro es correcta.
Gracias.
 
#7
Ok si es cableado largo no va el pullup.

Si es cableado largo mejor un optoacoplador con fuente aparte.

Hasta 20cm pullup
Hasta 1~5m inventos
+ De ahí optoacoplador y fuente aparte. 30m sin discusión
Interesante lo del optoacoplador, dices que use algo asi:
contar pulsos opto.PNG
Me parece muy buena idea, ademas agrega una "proteccion" extra contra las tormentas electricas (el controlador es para una parabolica)
Que optoacoplador seria recomendable usar?, tengo varios pc817. Son suficientemente rapidos para conmutar a esa velocidad?
 
#8
Lo complicado si lo hubiere en el lado del diodo. En el lado del transistor nada o casi porque se monta a 3mm del pin del Arduino. Ahí con el pullup requetesobra.
Principalmente bajar la impedancia lo que se pueda, incluso poner en paralelo con el led una resistencia para que no se encienda de ningun modo por corrientes inducidas.
Poner un diodo en antiparalelo por si entra algo al revés...

De todos modos yo es que soy adicto al aislamiento óptico. Habrá quien considere que no hace falta.
 
#9
Lo complicado si lo hubiere en el lado del diodo. En el lado del transistor nada o casi porque se monta a 3mm del pin del Arduino. Ahí con el pullup requetesobra.
Principalmente bajar la impedancia lo que se pueda, incluso poner en paralelo con el led una resistencia para que no se encienda de ningun modo por corrientes inducidas.
Poner un diodo en antiparalelo por si entra algo al revés...

De todos modos yo es que soy adicto al aislamiento óptico. Habrá quien considere que no hace falta.
Estoy probando con un pc817 y funciona perfecto, incluso quite el anti rebote por software y no tengo posicionamiento erroneo.
Voy a incluir en la PCB el optoacoplador :excelente:

En este caso deberia de tener en cuenta la corriente maxima soportada por el reed switch, son de este tipo no tiene ningun tipo de identificador:
MOT_Reed_switch-800x800.jpg

Solo me queda saber si la forma en que medi la frecuencia de los pulsos es correcta.
Muchas gracias!.
 

Adjuntos

#10
En esas pruebas estoy usando una sola fuente que en la salida tiene 2 reguladores 7812, uno para arduino y el otro para el optoacoplador.
se puede dejar asi? o es mejor colocar otro rectificador+filtrado exclusivo para el optoacoplador?
 
#11
Una sola fuente es como no optoacoplar al 95%

Usa interrupciones, el código es:
Interrupcion(){
Cuenta++
}
Y ya está
Lógicamente dentro del código de interrupción es inútil poner código antirrebotes. Si quieres usa un tóner que inhabilite la interrupción un tiempo.

Ya no me acuerdo bien pero me suena que hay un método directo de medir frecuencia en Arduino. Se comentó en el foro hace tiempo, yo nunca lo he usado.
 
#12
Una sola fuente es como no optoacoplar al 95%

Usa interrupciones, el código es:
Interrupcion(){
Cuenta++
}
Y ya está
Lógicamente dentro del código de interrupción es inútil poner código antirrebotes. Si quieres usa un tóner que inhabilite la interrupción un tiempo.

Ya no me acuerdo bien pero me suena que hay un método directo de medir frecuencia en Arduino. Se comentó en el foro hace tiempo, yo nunca lo he usado.
Si ya estoy usando las interrupciones, dentro de ella puse un codigo para que solo tome en cuenta una pulsacion mayor a 5 milisegundos y con eso funcionaba bien, la parabolica no tenia problemas de posicionamiento.
Pero con el optoacoplador funciono sin usar el anti-rebote.
 
#14
para medir bajas frecuencias digamos menos de 1000/500hz... en los AVR, se emplea el módulo ICP, (input capture), junto con el TIMER1 y la interrupción por icp,, y seguramente la interrupción por desborde, del timer1, si la frecuencia es extremadamente baja... (0,1hz p. e. )
Es el truco empleado al hacer un velocímetro de cadencia, para bici, moto, auto... así que es mortalmente exacto y con decimales esa lectura.... (y es igual en los PICs)
 
#15
para medir bajas frecuencias digamos menos de 1000/500hz... en los AVR, se emplea el módulo ICP, (input capture), junto con el TIMER1 y la interrupción por icp,, y seguramente la interrupción por desborde, del timer1, si la frecuencia es extremadamente baja... (0,1hz p. e. )
Es el truco empleado al hacer un velocímetro de cadencia, para bici, moto, auto... así que es mortalmente exacto y con decimales esa lectura.... (y es igual en los PICs)
Tendrías algún ejemplo en "codigo arduino"?.


Poner retardos en las interrupciones es pecado mortal. Poner bucles también.

Según mi criterio algo más que eso, pecado_mortal² o más pero yo es que soy talibán antiretardo.

5ms es una eternidad en tiempo de máquina, estás fundiendo unas 60000 instrucciones.
Comprendo tu punto, quizás me exprese mal, en realidad lo que hago es aumentar el contador de pulsos si la diferencia de tiempo entre el pulso actual y el anterior fue mayor a 5ms esta es la funcion ejecutada en cada interrupcion:
tiempoAntiRebote = 5000

JavaScript:
void sumarPulsosM1() { //debounce
if ((micros() - tiempoAnterior) >= tiempoAntiRebote) {
        motor1PulsosActuales = motor1PulsosActuales + 1;
        if ((motor1PulsosActuales == motor1PulsosDestino) /*|| (motor1PulsosActuales == motor1LimiteOeste)*/) {
            pararMotor1();
            guardarEstado(); // guardar estado actual
        }
    }
 tiempoAnterior = micros();
}
Si conecto el reedswitch del motor con ese codigo, la parabolica se posiciona perfectamente.
Pero si uso el optoacoplador como me sugeriste, puedo hacer esto sin problema:

JavaScript:
void sumarPulsosM1() { //debounce
        motor1PulsosActuales = motor1PulsosActuales + 1;
        if ((motor1PulsosActuales == motor1PulsosDestino) /*|| (motor1PulsosActuales == motor1LimiteOeste)*/) {
            pararMotor1();
            guardarEstado(); // guardar estado actual

        }
}
Si hago el conteo de esta forma, con el reed switch como se ve en el segundo diagrama la parabolica no se posiciona correctamente y el arduino cuenta entre 30 y 40 pulsos erroneos (pienso que entra de todo por el cable)
 
#16
Estuve haciendo pruebas con fuente separada y funciono todo bien. Voy a ver si consigo un optoacoplador rapido para mayor seguridad.
Que opinan de este diagrama:
cuentaPulsos.PNG

En este caso me conviene que R1 la resistencia de pullup sea mas baja que ese valor? si lo dejo asi cuando activo el optoacoplador la tension cae a unos pocos milivolts, pero si la pongo en 470 ohm por ejemplo la tension es de unos pocos voltios.
Al reedswitch lo atraviesan casi unos 30ma, sera mucho o no se va a desgastar rapido?.
Saludos.
 
#17
¿Rápido?
¿Para 20Hz?
Si los normales llegan a 20kHz, tienes un margen de 1000 veces. ¿Para que quieres más velocidad?¿Para luego quitársela con un condensador?¿Para que entre ruido?¿Para pagar más?¿Para filtrar la velocidad por software?
Yo no le veo sentido.

Cuidado con el concepto de "mejor".
Si tu optoacoplador tiene poca frecuencia a lo mejor es eso lo que filtra el ruido gratis, si le pones uno "mejor" tu circuito dejará de ir correctamente.
Hay mil ejemplos de casos similares, siempre pongo el de los leds; con una pila pequeña y unos cables cutres alimento un led que va de cine... "Mejoro" el circuito con una batería de menor resistencia interna, unos cables "mejores" de más sección y el led se quema porque pasa demasiada corriente. Tendría que limitarla con una resistencia. Así que pago más batería pago mas cables y va peor.
 
Última edición:
#18
Ya no me acuerdo bien pero me suena que hay un método directo de medir frecuencia en Arduino
Exactamente Scooter, con "pulseIn".
Dentro del enlace hay ejemplos. Es la forma mas sencilla de contar pulsos, pero tiene sus limitaciones.
# De 10 milisegundos (unos 100 hercios) a 3 minutos (180.000 milisegundos, unos 0,05 hercios).
# Se queda esperando al cambio de estado del pin, esto genera un "delay" importante dependiendo del tamaño del pulso y de la aplicacion.
 
#19
Exactamente Scooter, con"pulseIn".
Dentro del enlace hay ejemplos. Es la forma mas sencilla de contar pulsos, pero tiene sus limitaciones.
# De 10 milisegundos (unos 100 hercios) a 3 minutos (180.000 milisegundos, unos 0,05 hercios).
# Se queda esperando al cambio de estado del pin, esto genera un "delay" importante dependiendo del tamaño del pulso y de la aplicacion.
Ok voy a investigar como medir frecuencia con esa funcion. Estoy usando pulseInLong(pin, value, timeout) dentro del loop para detectar cuando el motor no envia pulsos y pararlo por seguridad, verifico si el motor se esta moviendo y si el resultado de pulseIn con 500ms de espera es 0, paro el motor.
Parece que funciona.
 
#20
Exactamente Scooter, con"pulseIn".
Dentro del enlace hay ejemplos. Es la forma mas sencilla de contar pulsos, pero tiene sus limitaciones.
# De 10 milisegundos (unos 100 hercios) a 3 minutos (180.000 milisegundos, unos 0,05 hercios).
# Se queda esperando al cambio de estado del pin, esto genera un "delay" importante dependiendo del tamaño del pulso y de la aplicacion.
Típico de muchas librerías de Arduino. Almuchas de ellas son una auténtica basura.

Sin ir mas lejos ¿Alguien sabe cuanto mas lento es hacer digitalWrite a un pin frente a un port?
Yo lo he medido y..
No es una ni dos ni tres ni diez ni vente veces mas lento, es unas CINCUENTA veces mas lento. No sé muy bien que fumaban los que hicieron las librerías de arduino pero algunas son para llorar.
 

Arriba