Problemas con ARDUINO UNO en la comunicación serial

Hola a todos, en un proyecto que estoy realizando me encontré con el siguiente problema, explico un poco cual es el funcionamiento, la idea es contar piezas producidas en tiempo real, la maquina libera un pulso de 24 volts, el cual paso por un revelador de 24v para cambiar de la señal de 24 a una 5v propia de arduino, una ves que llega dicha señal al arduino envió un mensaje serial, el problema se da de la siguiente manera, comienza trabajando bien y de pronto el led TX se queda encendido y deja de enviar los mensajes seriales, entonces tengo que desconectar el arduino y volver a conectarlo para que vuelva a enviar los mensajes seriales. Ya cambie la tarjeta pensando que fuera el hardware pero en todas las que he probado pasa lo mismo. Espero me puedan ayudar y les agradezco de antemano a todos su colaboración.

te recomiendo que uses un optoacoplador en vez del relé hace la misma función de aislamiento pero proporciona niveles más altos de velociudad de conmutación y durabilidad.

cual es la velocidad de las piezas que pasan por el sensor? no se estará saturando el puerto serie??

puedes poner el código??

Claro dame un segundo para comentarlo

const int buttonMaquina38 = 6;

int buttonStateM38 = 0;
int lastButtonStateM38 = 0;
unsigned long timeM38;
unsigned long timePulsoM38;
unsigned long diferenciaM38;

void setup() {
 pinMode(buttonMaquina38, INPUT);
 Serial.begin(9600);
}
void loop() {
timeM38 = millis();

 buttonStateM38 = digitalRead(buttonMaquina38);
 if (buttonStateM38 != lastButtonStateM38) {
   if (buttonStateM38 == HIGH) {
     diferenciaM38 = timeM38 - timePulsoM38;
     if (diferenciaM38 > 200){
     Serial.println("Maquina381");
     }
     timePulsoM38 = timeM38;
   }
 }
 lastButtonStateM38 = buttonStateM38;
}

Ademas no creo que se sature la comunicación ya que en las pruebas que he realizado eventualmente soporta 100 pulsos, 20, 5 es muy variable pero no logro observar una posible falla.

Lo que esta pasando es que la conmutación de tu relé de 24V esta generando ruido eléctrico y cuelga el Arduino.
Sigue el consejo de Go_zalo y usa un optoacoplador de este modo:


En lugar del LTV357T que tal vez no encuentres busca un 4N25 pero revisa los pines porque no creo que sean los mismos de la figura y usa una resistencia de 4k7 en el colector del fototransitor.


4N25

ok are algunas pruebas para ver que tal funciona, me causa algo de intriga que ese mismo diseño lo utilice en algunas otras ocasiones sin problema alguno y ahora que lo "optimice" tenga estas complicaciones, anexare el antes y después como referencia. Incluso en mi ultima versión utilice un jack rj45 para facilitar la conexión.

Ya realice algunas pruebas con el opto-acoplador que hasta el momento parece ser bastante estable, como el opto-acoplador recibe 3v y 13.65 mA entonces tenia que bajar los 24v de la fuente que utilice, entonces utilice un divisor de voltaje con un resistencia de 1k y otra de 6k. Este es el esquema, espero se entienda, no soy bueno con esto:


Asi se mira en la proto:

El divisor de voltaje:

Y el opto-acoplador 4N25

Ahora les muestro el programita que desarrolle en visual, donde muestro un conteo de pulsos, ademas en el sql realice un procedimiento almacenado para ingresarlo de forma mas rapida y en el programa utilice un hilo para escuchar el puerto com:

Modificare el circuito para probarlo en campo y ver que tal.

no está bien el divisor de tensión

el optoacoplador dices que el lado Led son 3v y 16ma

eso no quiere decir que tengas que poner 3v puedes poner 12 y el Led te quitará 3. entonces los ma se calculan como i=v/repsol por tanto r= v/I osea (12-3)/13.65m = 660

sol necesitas una resistencia de 660 en serie con el Led del optoacoplador y en serie con tu salida de 12v

pero la salida de no es de 12 si no de 24, aun que realice todas las mediciones de corriente y voltaje, pareciera funcionar bien, podrías explicarme mas o que problemas tendría. De antemano te agradezco los comentarios.

Una forma de ver si realmente se "satura" la comunicacion serie, seria cambiar a: Serial.begin(14400), o incluso Serial.begin(19200).
Si realmente es un problema de saturacion, ahora deberia desaparecer.
De no ser así está claro que sería, como dice surbyte un problema de ruido.

un divisor de tensión solo funciona cuando por la salida entre resistencia no sacas nada de corriente (o muy poca comparada con la corriente que circula entre ellas)

un diodo se comporta como una pila al reves en tu caso Didier el datasheet
3v pues quita 3v del circuito en que se encuentre

además en tu esquema con el interruptor abierto mandamos 3ma al Led y debería estar completamente apagado!!

perdon son 13ma no 30

el restado es 1.5kohm

Lo de que se sature no es, o almenos no parece pues por el momento lleva casi 8 horas y sigue enviando bien

Hola,el dia de hoy realice pruebas ya con el circuito en una tarjeta fenolica, las pruebas de "escritorio" fueron buenas, cuando lo trate de probar ya en "campo" se "trabo" o almenos es la forma en la que lo describiría, el arduino recibía los pulsos pero tardaba en mandarlos a la salida serial, después de un rato sin hacerle nada volvió a trabajar bien, mejoro considerablemente ya que ahora no se desconecta. Alguna idea gente, gracias de antemano.

Algo se filtra por tu fuente y cuelga el Arduino.
Deberías implementar un watchdog que básicamente es una rutina que es consultada periódicamente y si no responde quiere decir que el arduino esta tildado y entonces se autoresetea, pero en un arranque en caliente.

Arduino watchdog

tendría que cambiar el bootloader?, o almenos donde lo estoy mirando dice eso

ya puse el WatchDog, aun que no se si es correcto

#include <avr/wdt.h>
const int buttonMaquina38 = 2;

int buttonStateM38 = 0;
int lastButtonStateM38 = 0;
unsigned long timeM38;
unsigned long timePulsoM38;
unsigned long diferenciaM38;

void setup() {
  wdt_disable(); // Desactivar el watchdog mientras se configura
  pinMode(buttonMaquina38, INPUT);
  Serial.begin(9600);
  wdt_enable(WDTO_250MS); // Configurar a dos segundos
}

void loop() {
  wdt_reset(); // Actualizar el watchdog para que no produzca un reinicio
  timeM38 = millis();
 
  buttonStateM38 = digitalRead(buttonMaquina38);
  if (buttonStateM38 != lastButtonStateM38) {
    if (buttonStateM38 == HIGH) {
      diferenciaM38 = timeM38 - timePulsoM38;
      if (diferenciaM38 > 100){
      Serial.println("Maquina381");
      //digitalWrite(Salida, HIGH);
      }
      timePulsoM38 = timeM38;
    }
  }
  lastButtonStateM38 = buttonStateM38;
}