Conteo de pulsos con Arduino

pero usaste el flag para parar el motor?
acabo de probar el codigo que dejaste de prueba y funciona bien, un poco adaptado porque no tengo arduino, tengo un esp32

tu codigo:
Código:
void setup() {
 pinMode(7,OUTPUT); //motor
 pinMode(26,OUTPUT); // sentido giro
 pinMode(20,INPUT); //reed switch
 pinMode(14,INPUT_PULLUP); //boton
 Serial.begin(115200);
 attachInterrupt(digitalPinToInterrupt(20), sumarPulsosM1, CHANGE);
}
int boton = 0;

void sumarPulsosM1() {
  digitalWrite(7, LOW);
  detachInterrupt(digitalPinToInterrupt(20)); //aca para la interrupcion
}

void loop() {
  boton = digitalRead(14);
 if (boton == 0){
    Serial.println("pulso");
    delay(100);
    digitalWrite(7,HIGH);
    delay(1000);
  }
}

el codigo para esp32 usasndo el touch con flag:
Código:
int threshold = 40;
byte button;
byte motor= 2;
bool flag= 1;
void gotTouch1(){
 flag=0;
}

void setup() {
  Serial.begin(115200);
  pinMode(2,OUTPUT); //motor
  digitalWrite(2, 1);
  touchAttachInterrupt(T7, gotTouch1, threshold);
}
int boton = 1;
void loop(){
  Serial.println(digitalRead(motor));
  if(flag==0){
    digitalWrite(2, 0);
  }
 if (boton == 0){
  flag=1;
    Serial.println("pulso");
    delay(50);
    digitalWrite(2,HIGH);
  }
}

sin flag:
Código:
int threshold = 40;
byte button;
byte motor= 2;
bool flag= 1;
void gotTouch1(){
  digitalWrite(2, 0);
}

void setup() {
  Serial.begin(115200);
  pinMode(2,OUTPUT); //motor
  digitalWrite(2, 1);
  touchAttachInterrupt(T7, gotTouch1, threshold);
}
int boton = 0;
void loop(){
  Serial.println(digitalRead(motor));
 if (boton == 0){
    Serial.println("pulso");
    delay(50);
    digitalWrite(2,HIGH);
  }
}
 
Probé usar el flag para parar el motor y si se para, lo que pasa es que dentro del loop tengo mas cosas, compruebo los botones,leo el serial,etc
Entonces en algún momento puede suceder que no se pare donde debe.
Yo creo que el problema esta en mi arduino o en algo relacionado a manejar los puertos con las interrupciones, porque el codigo ese es bastante simple y falla de la misma forma que todo el codigo completo.
 
Pero en el loop copias la bandera al pin.
Así siempre se copia y siempre parará
Ok, yo lo habia hecho mal:
Código:
if (parar == true){
digitalWriteFast(pin,LOW);
}

Ahora lo hice de esta forma dentro del loop:
Código:
digitalWrite(motor1PWR, estadoMotor);
Pero igual lo para un pulso o 2 después.
Igualmente me parece raro que suceda esto
Ahora estoy probando en modo RISING, no tengo tanta precisión como en modo CHANGE pero funciona y se para donde debe.
Mas o menos lo moví unos 4000 pulsos y tuve 0 pulsos erróneos.
Con que tenga un pulso de mas o menos ya afecta un poco en las señales muy débiles. Por eso lo quiero dejar que funcione lo mejor posible.
Encontré esto, no entiendo muy bien pero creo que es similar a mi problema:
digitalWrite & pinMode unsafe from interrupts [imported] · Issue #146 · arduino/Arduino

Principalmente acá:
the pin will be driven HIGH for a brief time before it is written LOW. If an interrupt
occurs, a substantially long HIGH pulse could occur
, when the user expects
a 1% duty cycle to become LOW. The output register should be updated
before PWM is disabled so when the pin returns to the control of the output
register it will have the correct value.[/CODE]

Quizás no tenga nada que ver.

Edit: encontre esto tambien:
DigitalWrite during interrupts
 
Luego seguiré intentando resolver ese problema. Ya vi en otros foros otros usuarios con problemas similares.

Anteriormente me comentaron de utilizar un sensor hall y veo que hay actuadores que vienen con ese sensor.
Mi idea de este proyecto es hacerlo "modular" para el que lo quiera construir. entonces quiero hacer otra controladora para actuadores con sensor hall.
Creen que si le cambio el reed switch por un sensor hall al que yo tengo funcionara?
Así es la disposición de los imanes: (pero centrado jajaja)
Sin título.jpg
Luego les subo una foto real.

Es un engranaje grande con 4 o 6 imanes no recuerdo exactamente y el reed switch esta debajo de los imanes.
Si pongo el sensor hall en el mismo lugar, funcionara?

El sensor hall, ya da un pulso digital?, conviene opto acoplarlo de la misma forma que al reed switch?.
Que sensor me recomiendan para probar?.
 
Les dejo unas imágenes:

Este es similar al actuador que estoy usando ahora:
dsc02039-jpg.119936
 
Estuve haciendo mas pruebas con el problema de que el pin no cambia de estado y solo sucede cuando el motor gira muy rápido.
Y eso explica porque antes no me había dado cuenta ya que tenia una lampara en serie y la tensión caía un poco.
Hice un sketch que lo activa por 1 segundo y cuenta los pulsos, alimentado con 24vcc cuenta 15 pulsos por segundo y a 36vcc (como debería de funcionar) da unos 23-25 pulsos por segundo. me parece poco pero bueno me voy a tener que conformar con usar las interrupciones en modo RISING.
En el foro de arduino me comentaron que el bug 146 ya fue resuelto hace mucho tiempo.
Tendría que probar con un arduino mas rápido a ver que sucede. pero la idea es que esto sea lo mas económico y fiable posible para el que este interesado en construirlo.
 
da unos 23-25 pulsos por segundo
Tendría que probar con un arduino mas rápido a ver que sucede
:oops::oops::oops::oops::oops::oops:
25 pulsos por segundo es una eternidad para el Arduino!!!!
Tendrás que pensar mejor el código, por que le recontra-sobra tiempo para contar y hacer muchas cosas mas!
Y si nó, mandá los pulsos a la entrada externa de uno de los timers y contás por hardware (consumo de CPU=0%) y cada cierto tiempo vas y mirás como va el timer para operar sobre el motor.

PD: Si el posionamiento exacto es taaaaaaan importante, no podés zafar de meter un control PI de posición.
 
Más bien fallará el sensor
25Hz es lastimosamente hiper ultra super lentísimisimo.

Para un contacto mecánico, depende. Para algunos es inalcanzable. Para otros puede que lleguen o les sobre algo. No mucho.

Sensor hall, sin duda

O sensor óptico, con las diferencias de color que hay seguramente irá uno reflexivo sin más.
 
Por ahora como lo estoy probando en modo RISING se posiciona bien y para donde debe. pero en modo CHANGE tiene un movimiento mas preciso.
Entiendo que los pulsos son muy lentos, pero algo raro tiene que haber.
El código de mas arriba es ultra sencillo y solo con eso ya se puede recrear el fallo.
Para mi el conteo debe de estar dentro de las interrupciones porque dentro del loop tengo que hacer varias cosas:
Leer puerto serie para comunicarme con un PIC (primero verifica si hay algo para leer)
Leer puerto serie para comunicarme con la PC (primero verifica si hay algo para leer)
Leer la pulsación de los botones
Dibujar la LCD cada X tiempo (codigo sin delay, no bloqueante)
Verificar que si el motor esta encendido el conteo de pulsos cambie, si no hay que parar el motor por seguridad.

Creo que si hago el conteo dentro del loop voy a tener problemas ya que existe la posibilidad de que cuando el arduino este ocupado haciendo algo de eso, el reed switch cambie de estado y no lo cuente.

Ademas de eso, cuando el motor se mueve y el receptor no recibe señal, cada 1 segundo mas o menos envía un comando DISEQC para que conmute la entrada y ahí ya estaría procesando algo dentro del loop mientras el motor se mueve.

Tengo un vídeo:

El led azul de la PCB muestra cuando el reed switch conduce o no.
El led rojo es una prueba para apagar otro pin dentro de la interrupcion.

El funcionamiento es el siguiente:
Presiono botón
Activa la interrupcion
Activa el pin del motor
Motor se mueve
reed switch dispara la interrupcion
la interrupción suma 1 a la cuenta
apaga el led rojo de prueba (pin diferente del motor)
apaga motor
desactiva la interrupción (para mostrar mas claro el fallo)

Como ven las primeras pulsaciones anda bien, porque la parabólica esta hacia un lado, cuando toma mas velocidad falla y nunca se ejecuta el digitalWrite de la interrupción. Entonces sigue de largo al igual que el led sigue encendido.
Si dejo siempre la interrupción activa, se dispara 2 o 3 veces hasta que ahí si apaga los pines y el motor para.
En un principio pensé que era la inercia del motor, pero si fuera eso debería de apagar los pines y listo.
Cambien pensé en la FEM del motor pero tiene el diodo, capacitor, esta optoacoplado, fuente separada. Hasta le puse otro diodo al motor directo y un varistor para probar pero hace lo mismo.
Solo funciona si le bajo la tensión al motor y gira mas lento.

En el foro de arduino me dijeron que el reed switch rebota, pero si ese fuese el problema igualmente debería de pararse y hasta contar mal los pulsos pero en realidad son pulsos reales los que cuenta.
Voy a probar esto en un arduino UNO a ver que pasa.
 
Lo has dicho ya varias veces.
Cambia el sensor.
"Despacio va y cuando adquiere velocidad no"
"Solo va si le bajo la tensión al motor y va más lento"
Al Arduino le sobra velocidad por todas partes, salvo que lo enfangues a delays, pero estás usando interrupciones.

Cambia el sensor
 
Lo has dicho ya varias veces.
Cambia el sensor.
"Despacio va y cuando adquiere velocidad no"
"Solo va si le bajo la tensión al motor y va más lento"
Al Arduino le sobra velocidad por todas partes, salvo que lo enfangues a delays, pero estás usando interrupciones.

Cambia el sensor

Ok, mas arriba subí una imagen de como es la disposición de los imanes, colocando el sensor hall debajo tal cual esta el reed switch es suficiente?.

Igualmente no entiendo porque motivo sucede eso.
 
Pues más que evidente, todas las cosas del universo tienen inercia. Las cosas mecánicas más inercia. Las cosas electrónicas menos inercia.
Para mover físicamente un contacto no lo puedes hacer a la velocidad que quieras, cuanto más rápido más fuerza tienes que hace para tener más aceleración porque la distancia a mover es la misma y la masa la misma, como la fuerza del imán es constante llega un momento que no tienes bastante aceleración y no se mueve bastante para abrir y cerrar. Como eso no es todo-nada antes de dejar de ir hay un intervalo en el que va regular, y a veces irá y a veces no, según la posición etc.
Con algo electrónico irá miles de veces más rápido hasta que también llegue a su límite...


Todo eso sí es el sensor como parece. Puede ser cualquier otra cosa, no lo sabrás hasta que aciertes con las investigaciones...

De todos modos 10Hz es bastante para algo mecánico.
 
Pues más que evidente, todas las cosas del universo tienen inercia. Las cosas mecánicas más inercia. Las cosas electrónicas menos inercia.
Para mover físicamente un contacto no lo puedes hacer a la velocidad que quieras, cuanto más rápido más fuerza tienes que hace para tener más aceleración porque la distancia a mover es la misma y la masa la misma, como la fuerza del imán es constante llega un momento que no tienes bastante aceleración y no se mueve bastante para abrir y cerrar. Como eso no es todo-nada antes de dejar de ir hay un intervalo en el que va regular, y a veces irá y a veces no, según la posición etc.
Con algo electrónico irá miles de veces más rápido hasta que también llegue a su límite...

Todo eso sí es el sensor como parece. Puede ser cualquier otra cosa, no lo sabrás hasta que aciertes con las investigaciones...

De todos modos 10Hz es bastante para algo mecánico.

Hice otra prueba, la precisión que tiene el posicionador chino generico que tengo es exactamente la misma que este que estoy haciendo contando los pulsos en modo RISING, así que supongo solo contara un pulso al pasar de 0 a 1

Solo tiene un PIC, 4 transistores, 2 relees,unas pocas resistencias y capacitores, algún inductor.

Conseguí un diagrama de un posicionador de mejor calidad que el chino que tengo, tiene la entrada del reed switch optoacoplada como me recomendaste.
Y unos varistores en las entradas/salidas, puedo usar un varistor de la tensión del motor o con la FEM del motor se destruye?.
La idea es ponerle a la entrada del reed switch, la entrada del motor y la fuente para protegerlo un poco de las tormentas eléctricas.

Sobre los sensores hall,cual de estos sensores sera mejor:
KY-003
17-02.jpg

Ky-024
KY-024_linear_magnetic_hall_sensor_module_arduino.jpg

Segun vi en el datasheet, la salida parece ser de un transistor, puedo activar directo el optoacoplador desde ahi o no es necesario?
 

Adjuntos

  • diagrama vbox.pdf
    80.3 KB · Visitas: 8
El segundo circuito es una ultragilipollez de los chinos vendehumos; el sensor hall que lleva ya tiene salida digital con toda la circuitería dentro. Ese circuito es recontraabsurdo.
El primero ya es digital y lleva dentro todas las bendiciones apostólicas.
Cuidado porque tiene polaridad magnética, puede que funcione en un sentido y en el otro no.
Puede que tus imanes estén alternados.

Cuidado también porque se basan en un sensor de allegro obsoleto, no pasa nada, pero si mas adelante quieres fabricar una serie te va a ser complejo encontrar los sensores. Si solo vas a hace este o poco mas, compras unos cuantos al chino y listo.
 
Osea que para que funcione debo de tener los imanes con la polaridad alternada o todos iguales?.

Otra duda que tengo, deje de usar digitalWriteFast y ahora uso bitWrite, setBit y bitClear para activar/desactivar los pines.
Puse un flag dento de la interrupción como me recomendaron y lo escribo al puerto dentro del loop, afecta el tiempo de vida del arduino estar continuamente escribiendo el estado de un pin? debería de verificar primero si es necesario cambiar el estado?.
 
Última edición:
Todos iguales, si están alternados irá en la mitad que estén bien orientados.
No se gastan los pines por reescribir.
Lo único que se gasta es la EEPROM y la flash
 
:oops::oops::oops::oops::oops::oops:
25 pulsos por segundo es una eternidad para el Arduino!!!!
Tendrás que pensar mejor el código, por que le recontra-sobra tiempo para contar y hacer muchas cosas mas!
Y si nó, mandá los pulsos a la entrada externa de uno de los timers y contás por hardware (consumo de CPU=0%) y cada cierto tiempo vas y mirás como va el timer para operar sobre el motor.

PD: Si el posionamiento exacto es taaaaaaan importante, no podés zafar de meter un control PI de posición.

Te refieres a que use por ejemplo el timer 5 de forma que cada vez que reciba un pulso sume 1 y después con otro timer por ejemplo el 4 cada 5ms leo la cantidad de pulsos y actuo sobre el motor?.
 
Ya encargue unos sensores hall para probar, tiene algún sentido usar este diagrama o como deberían de ir?
hall.PNG

Este es el diagrama para conectar el reed switch en un vbox2 que es un posicionador comercial
entrada pulsos vbox2.PNG

No se que función cumple D3, en mi diagrama puse C1 porque en las pruebas que hice se encendía el led al desactivar un relee.
 
Atrás
Arriba