Problema con la detección de pulsos(Solucionado, grax por ayudar <3)

Buenas noches, hoy estaba trabajando con un contador de pulsos. Pongo todo en contexto, tengo 2 arduinos, uno se encarga de enviar pulsos según el botón que haya pulsado, tengo 4 botones donde solo 2 son funcionales pero por pruebas, después los habilito, pues bien, el primer botón se encarga de enviar 1 pulso, y el segundo 2 pulsos. Eso funciona bien, ahora tengo problemas para el tema de leer pulsos, pues lo que no consigo es que lea los 2 pulsos en caso de que se pulse el botón dos. Llevo un rato partiéndome la cabeza y buscando por ahí pero no consigo nada, haber si me podéis echar un cable, gracias.

Una cosa que no he dicho, es que los arduino los he conectado de la siguiente forma:

  • Un GND de cada arduino conectados entre sí.
  • El pin 9 del emisor de pulsos al pin lector de pulsos que es el 2.

Ahora dejo código de los dos arduino por si sirve el del emisor.

//EMISOR DE PULSOS
#define btn1 4
#define btn2 5
#define btn3 6
#define btn4 7
#define pinOut 9

struct buttonVar {
  byte pin;
  bool state;
  bool lastState;
};
struct buttonVar btn[] = {
  {btn1, 1, 1},
  {btn2, 1, 1},
  {btn3, 1, 1},
  {btn4, 1, 1}
};

int debounceTime = 20;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (byte i = 0; i < 5; i++){
    pinMode(btn[i].pin, INPUT_PULLUP);
  }
  pinMode(pinOut, OUTPUT);
  digitalWrite(pinOut, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  btn[0].state = digitalRead(btn[0].pin);
  btn[1].state = digitalRead(btn[1].pin);
  btn[2].state = digitalRead(btn[2].pin);
  btn[3].state = digitalRead(btn[3].pin);
  if(btn[0].state != btn[0].lastState){
    if(btn[0].state == 1){
       digitalWrite(pinOut, HIGH);
       Serial.println("btn1");
       delay(debounceTime);
       digitalWrite(pinOut, LOW);
    }
  }
  btn[0].lastState = btn[0].state;
  //--------------------------
  if(btn[1].state != btn[1].lastState){
    if(btn[1].state == 1){
       digitalWrite(pinOut, HIGH);
       Serial.println("btn2");
       delay(debounceTime);
       digitalWrite(pinOut, LOW);
       digitalWrite(pinOut, HIGH);
       Serial.println("btn2");
       delay(debounceTime);
       digitalWrite(pinOut, LOW);
    }
  }
  btn[1].lastState = btn[1].state;
  //--------------------------
  /*if(btn[2].state != btn[2].lastState){
    if(btn[2].state == 1){
       Serial.println("btn3");
    }
  }
  
  btn[2].lastState = btn[2].state;
  //--------------------------
  if(btn[3].state != btn[3].lastState){
    if(btn[3].state == 1){
       Serial.println("btn4");
    }
  }
  btn[3].lastState = btn[3].state;
  //--------------------------*/
}
//LECTOR DE PULSOS
#define btn 2
int pulseCount;

bool btnState;
bool btnLastState = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btn, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    for(byte i = 0; i < 4; i++){
       btnState = digitalRead(btn);
       if(btnState != btnLastState){
         if(btnState == HIGH){
         pulseCount++;
        }
      }
      btnLastState = btnState;
    }
  
  Serial.println(pulseCount);
  /*if(pulseCount == 1){
     Serial.println(1);
     //pulseCount = 0;
  }else if(pulseCount == 2){
    Serial.println(2);
    //pulseCount = 0;
  }else if(pulseCount == 3){
    Serial.println(3);
    //pulseCount = 0;
  }else if(pulseCount == 4){
    Serial.println(4);
    //pulseCount = 0;
  }*/
}

Buenas, si no entiendo mal tu problema es que no te toma las 2 pulsaciones, ahora tal vez necesites poner un 'while' de modo que hasta que no se den 2 pulsos no sale de tal bucle. Saludos.

En tu Arduino generador de pulsos envias pulsos cada 20 mseg (debounceTime) según esto

digitalWrite(pinOut, HIGH);
       Serial.println("btn2");
       delay(debounceTime);
       digitalWrite(pinOut, LOW);

Un for() scannea a mucha mas alta velocidad que 20 mseg de modo que no aclanzas en 4 o 5 iteracciones a detectar esos cambios.

Tu código debe ser algo mas inteligente si lo quieres hacer bien, y de lo contrario consume tiempo esperando a que se den las condiciones posibles y luego libera. Eso lo harás con la sugerencia de @hypernovat usando un while

En lo personal yo usaría una modificación a lo que has programado : En lugar de ver cambios y luego reaccionar ante el estado alto, simplemente miraría el flanco 0 a 1 así

    btnState = digitalRead(btn);
    if (btnState && !btnLastState){
         pulseCount++;
    }
    btnLastState = btnState;

Ahora esto te detecta todos los pulsos que entren por el pin btn.
Lo único que te falta es una ventana de tiempo para poner a 0 pulseCount.
Si usará una ventana de tiempo de 100 mseg podría leer con precisión hasta 4 pulsos de 20 mseg.

eso lo haces así definiendo previamente como

unsigned long start;
if (millis() - start > 100UL) {
    Serial.println(pulseCount); // imprimo cuantos pulsos fueron leídos en los últimos 100 msg
    pulseCount = 0;
}

A ver si funciona esta parte correctamente.

Vale, muchísimas gracias, probaré todo y ya diré si fue bien

Ok, he conseguido lo siguiente:

#define btn 2
int pulseCount;

bool btnState;
bool btnLastState = 0;

long i;
unsigned long start;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btn, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(btn)==1){
    i++;
    }//Esto es para guardar en i las veces que recibe 1 y así poner "límite" al while.
  while(pulseCount <= i){
    btnState = digitalRead(btn);
    if((btnState && !btnLastState)){
      pulseCount++;
    }
    btnLastState = btnState;
  }
  Serial.println(pulseCount);
}

Pero no he conseguido implementar para que se reinicie el contador de pulsos, llevo ya un rato intentando asignarlo pero ninguna de las formas que he intentado lo hace bien.

surbyte:

unsigned long start;
if (millis() - start > 100UL) {

Serial.println(pulseCount); // imprimo cuantos pulsos fueron leídos en los últimos 100 msg
    pulseCount = 0;
}




A ver si funciona esta parte correctamente.

Prueba esto

#define btn 2
int pulseCount;

bool btnState;
bool btnLastState = 0;

long i;
unsigned long start;
bool flag = false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(btn, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    btnState = digitalRead(btn);
    
    if ((btnState && !btnLastState)){ // esto lee pulsos que pasan de 0 a 1
         pulseCount++;
         flag = true;                 // con el primer pulso inicio el timer
    }
    btnLastState = btnState;

    if (flag) {     // esto arranca con el primer pulso
        if (millis() - start > 100UL) { // a los 100 mseg lo detengo
            Serial.println(pulseCount); // y preparo para la proxima secuencia.
            pulseCount = 0;             // si 100 es mucho lo bajo a 50 o menos
            flag = false;
        }
    }
}

Surbyte, muchas gracias por tu tiempo, y gracias por los comentarios del código, así pude entenderlo mejor. Eres el mejor macho.