Interrupción + contador de tren de pulsos: no funciona correctamente

Estimados amigos del foro, ¡muy buenos días!

Me veo en la necesidad de realizar un post para ver si entre todos podemos dar con la solución al problema que les comentaré a continuación...

Descripción del proyecto:
Estoy desarrollando un sistema que centraliza en una PC (que actúa como servidor), la información recibida de 3 arduinos. Todos los arduino son MEGA 2560.
-Dichos arduinos actúan de "surtidores de combustible", puesto que cuentan la cantidad de litros que se cargan en distintos tanques y luego envían el resultado (cantidad de litros cargada) + el n° del cliente al servidor, de forma tal de almacenar en una base de datos la cantidad de litros que cargó tal cliente.
-La visualización in situ en los surtidores (cada arduino), se efectua en una matriz de puntos de 8x1.

Problema:
El conteo de litros se va a efectuar mediante un caudalímetro, que entrega una x cantidad de pulsos.
Pero, para no tener que efectuar pruebas en el lugar, pensé en desarrollar un generador de pulsos para "emular" la salida del caudalímetro y, para evitar fabricar uno, se me ocurrió usar uno de los arduinos para generar los pulsos a modo de poder efectuar pruebas en la empresa.

Hasta aquí, me pareció super sencillo, pero como pasa muchas veces, algo se me está pasando y no funciona la parte del conteo como debería.

Código del arduino generador de pulsos:

int counter_out = 44;                             // PIN DE SALIDA HACIA EL ARDUINO QUE CUENTA
int retardo = 500;                                // RETARDO ENTRE PULSOS PARA PODER VISUALIZAR CORRECTAMENTE
int contador = 0;
/*********************************************/
void setup() {
         Serial.begin(9600);
         pinMode(13, OUTPUT);                     // CONFIGURA PIN 13 COMO SALIDA
         pinMode(counter_out, OUTPUT);            // CONFIGURA PIN 44 COMO SALIDA
}
/*********************************************/
void loop() {
         do{
            digitalWrite(counter_out, HIGH);
            digitalWrite(13, HIGH);               // VISUALIZO EN EL LED INTEGRADO QUE LA SECUENCIA ESTÉ BIEN
            delay(retardo);
            digitalWrite(counter_out, LOW);
            digitalWrite(13, LOW);
            delay(retardo);
            contador++;
            Serial.println(contador);
         } while (contador <= 1000);
         contador = 0;
}

Monitor serie:

09:34:33.860 -> 1
09:34:34.855 -> 2
09:34:35.886 -> 3
09:34:36.878 -> 4
09:34:37.911 -> 5
09:34:38.904 -> 6
09:34:39.929 -> 7
09:34:40.928 -> 8
09:34:41.921 -> 9
09:34:42.949 -> 10
09:34:43.943 -> 11
09:34:44.967 -> 12
09:34:45.961 -> 13
09:34:46.987 -> 14
09:34:47.984 -> 15

Código del arduino contador:

#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>

/*
 * DEFINICIÓN DE VARIABLES Y CONSTANTES PARA MATRIZ DE PUNTOS
 */
const int pinCS = 53;                               // CAMBIAR EN FUNCIÓN DEL TIPO DE ARDUINO
const int numberOfHorizontalDisplays = 8;           // CAMBIAR EN FUNCIÓN DE LA CANTIDAD DE COLUMNAS QUE TENGA LA MATRIZ
const int numberOfVerticalDisplays = 1;
const int spacer = 1;
const int width = 5 + spacer;                       // Ancho de la fuente a 5 pixeles (SE PUEDE CAMBIAR LA FUENTE)
int length;                                         // VARAIBLE DINÁMICA POR LIBRERÍA P/LARGO DE TEXTO
String msj;                                         // VARIABLE PARA ALMACENAR PROVISORIAMENTE LOS MENSAJES A MOSTRAR

Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); // CONTROL POR LIBRERÍA PARA MATRIZ DE PUNTOS

/*
 * DEFINICIÓN DE VARIABLES Y CONSTANTES DEL PROGRAMA
 */
const int interruptPin = 2;
volatile int contador = 0;
volatile byte estado_anterior = 0;
volatile byte estado_actual;
const int ledPin = 13;
unsigned int valor_anterior = 0;


/*
 * SETUP PRINCIPAL
 */
void setup() {
          Serial.begin(9600);
      
          pinMode(ledPin, OUTPUT);                    // CONFIGURA PIN 13 COMO SALIDA
          digitalWrite(ledPin, LOW);                  // APAGA EL LED CONECTADO INTERNAMENTE AL PIN 13
          
          pinMode(interruptPin, INPUT_PULLUP);
          attachInterrupt(digitalPinToInterrupt(interruptPin), ISCounter, RISING);
          
          matrix.setIntensity(2);                     // AJUSTA EL BRILLO DE LA MATRIZ - 0-15
            
          matrix.setPosition(0, 0, 0);                // El primer display esta en   <0, 0>
          matrix.setPosition(1, 1, 0);                // El segundo display esta en  <1, 0>
          matrix.setPosition(2, 2, 0);                // El tercer display esta en   <2, 0>
          matrix.setPosition(3, 3, 0);                // El cuarto display esta en   <3, 0>
          matrix.setPosition(4, 4, 0);                // El quinto display esta en   <4, 0>
          matrix.setPosition(5, 5, 0);                // El sexto display esta en    <5, 0>
          matrix.setPosition(6, 6, 0);                // El séptimo display esta en  <6, 0>
          matrix.setPosition(7, 7, 0);                // El octavo display esta en   <7, 0>
          matrix.setPosition(8, 8, 0);                // El noveno display esta en   <8, 0>
         
          matrix.setRotation(0, 3);                   // Posiciones de los displays
          matrix.setRotation(1, 3);
          matrix.setRotation(2, 3);
          matrix.setRotation(3, 3);
          matrix.setRotation(4, 3);
          matrix.setRotation(5, 3);
          matrix.setRotation(6, 3);
          matrix.setRotation(7, 3);
          matrix.setRotation(8, 3);
}


/*
 * LOOP PRINCIPAL
 */
void loop() {
          if (contador != valor_anterior){
              Serial.println(contador);
              valor_anterior = contador;
              escritura();
          }
}


/*
 * INTERRUPCIÓN
 */
void ISCounter() {
              contador++;
}

/*
 * RUTINA PARA ESCRITURA EN LA MATRIZ DE LEDS - cambiar el número de displays - 8 por defecto                  */
 */
void escritura () {
            msj = "C:" + String(contador) + " L";
            length = msj.length() * width;                                  /* SETEOS DE LONGITUD DEL MENSAJE */
              for (int i = numberOfHorizontalDisplays*8-length; i>0; i--)   /* SI ES REQUERIDO, RELLENA CON ESPACIOS EN BLANCO EL RESTO DE LA MATRIZ NO ESCRITA */
                msj += " ";
                                                                            /* ESCRITURA */
            matrix.setCursor((numberOfHorizontalDisplays*8-length)/2,0);    /* CENTRA EL TEXTO */ 
            matrix.fillScreen(LOW);
            matrix.print(msj);                                              /* MENSJAE A IMPRIMIR */
            matrix.write();
            //delay(500);
}

Monitor serie del arduino contador:

10:10:21.008 -> 3
10:10:21.008 -> 4
10:10:21.043 -> 7
10:10:21.043 -> 8
10:10:21.043 -> 10
10:10:21.078 -> 12
10:10:21.078 -> 17
10:10:21.078 -> 18
10:10:21.078 -> 19
10:10:21.112 -> 20
10:10:21.112 -> 21
10:10:21.112 -> 22
10:10:21.146 -> 25
10:10:21.146 -> 26
10:10:21.146 -> 33
10:10:21.180 -> 34
10:10:21.180 -> 37
10:10:21.180 -> 38
10:10:21.180 -> 41

Como pueden observar, la cuenta es totalmente errónea y de hecho incrementa el contador en fracciones de segundo. Muy distinto a lo que está recibiendo.

Seguidamente, modifiqué un poco la rutina de la interrupción:

void ISCounter() {
          estado_actual = digitalRead(interruptPin);
          
          if (estado_actual != estado_anterior){
              estado_anterior = estado_actual;
              contador++;
          }
}

Obtengo el mismo resultado.

Si desconecto el pin 44, la cuenta se detiene.
Pero (y para mi sorpresa) si por ejemplo conecto el arduino generador de pulsos en otro pin (40,42,46, etc), la cuenta se reanuda y obtengo mismo resultado. :o :o :o

Entonces me desconcertó porque no se que es lo que está leyendo.
Probé cambiar la llamada a la interrupción (LOW, HIGH; FALLING), mismo resultado.

¿Alguna idea de lo que puede estar ocurriendo?

Disculpen la extensión, pero traté de ser lo más explícito posible.

Aguardo sus comentarios, saludos!

Para comenzar, si los pulsos de tu caudalímetro van a ser TAN LENTOS como algo cada 500 mseg para que quieres interrupciones? Seguramente no lo sabes pero las interrupciones fueron pensadas para otra cosa aunque es cierto que deberían funcionar bien.

Yo en tu caso haría una simple rutina que tal como lo planteas funcionaría perfectamente pero.. tu simulador no se si se ajusta a un caludalimetro de combustible. Me parece que es una aproximación como para comenzar.

Antes de gastar mi tiempo en darte un código quisiera que seas mas preciso en esto y cuando hablo de precisión me refiero a que nos digas que caudalímetro y el rango de pulsos que tiene para su lectura normal.
Supongo que la bomba de combustible trabaja a cierta RPM y por lo tanto tenemos un caudal constante y eso se traduco en X cantidad de pulsos por segundo? cuantos? es exactamente lo que has puesto, uno cada 500 mseg?

Exactamente, tal y como bien dices, es solo un modelo de aproximación.

Inicialmente lo hice LENTO para poder ver la cuenta en la matriz de leds y corroborar que todo funciona bien.
Luego ese "retardo = 500" lo bajaré considerablemente para igualarlo a los pulsos que arroje el caudalímetro.

Los pulsos exactos del caudalímetro no los tenemos aún, puesto que es un caudalímetro que no logramos conseguir su datasheet y esta empresa no desea cambiarlo (y le hemos sugerido el cambio).
Esto no nos preocupa demasiado dado que, el día que lo instalemos, haremos circular 100, 500, 1000 litros de un tanque a otro en reiteradas ocasiones y contaremos los pulsos. En base a eso sacaremos la relación pulsos x litro.
De ahí lo anterior de realizar el generador con el arduino para simular distintos escenarios (cantidad de pulsos x segundo). En definitiva, si es más rápido debería funcionar igualmente bien.

Cuando se realice la instalación, simplemente ajustaré la relación pulsos x litro a "la real".
Soy consciente que al no tener la hoja de datos, el otro método puede no arrojar el valor exacto de pulsos x litro, pero, ante la negativa de cambiar los caudalímetros, es una muy buena aproximación.

Continuando, lo pienso hacer por interrupción, dado que el programa mientras "cuenta", al mismo tiempo realiza otras operaciones, por ejemplo, de comunicación con el servidor.

Una pregunta muy básica (para descartar) ¿conectaste las masas de los Arduino entre si?

Bueno, a mi me sorprende la "liviandad" con la que manejas cuestiones anti-explosivas.
Debes tener mucho cuidado en lo que hagas, pero supongo que sabes del tema y por eso no le prestas atención. Yo me manejo en ambientes explosivos y estas cosas asi no pueden hacerse y menos con elementos no certificados y siempre hay que usar barreras intrinsicamente seguras.

Me encanta Arduino pero cada cosa en su sitio.
Supongamos que nadie lee esto.. entonces, continuemos.

Okay, si ese es el caso y suponemos que los pulsos aumentarán en frecuencia, entonces, tal vez si haya que prestar atención a lo que ocurre.

Tu arduino Generador comparte GND con el Arduino lector de pulsos? No descarto eso porque no lo has mencionado.
Otra cosa importante es los cables que usas. Son apantallados? Tienen puesta a tierra?

Eso que hiciste en la rutina de interrupcion no tiene sentido alguno.
Tu interrupción ve RISING asi de que cambio podemos hablar?
Ademas, la interrupción ya se activo por RISING o sea de 0 a 1, que sentido tiene leer el estado del pin? Nada. 0.

void ISCounter() {
          estado_actual = digitalRead(interruptPin); // SIN sentido
         
          if (estado_actual != estado_anterior){  // no hay cambio posible
              estado_anterior = estado_actual;
              contador++;
          }
}

NOTA: esta respuesta la escribí temprano pero me fui y no la postee. Asi que tal vez alguien pregunte o afirme lo mismo que yo.

Otterstedt:
Si desconecto el pin 44, la cuenta se detiene. Pero (y para mi sorpresa) si por ejemplo conecto el arduino generador de pulsos en otro pin (40,42,46, etc), la cuenta se reanuda y obtengo mismo resultado. :o :o :o

Debo adivinar que el pin 44 del Arduino "generador de pulsos" esta conectado al pin 2 del Arduino "contador" que esta con PULLUP por software y que ambas GND estan también unidas, pero me queda la duda del tipo de cable (es coaxial ?) que usaste y cuanto mide este ?