Proyecto de contador de pulsos individuales

Hola, ante todo gracias a todos por molestarse en leerlo, bueno ahora va mi pregunta para haber si alguien me puede ayudar, porque yo de programación estoy muy cortito. Estoy intentando hacer un aparatito que cuente hasta doce pulso individuales, y que valla mostrándolo en pantalla e empezado con bastante menos pulsadores porque la verdad, es que no tengo ni idea por internet solamente encuentro con un solo pulsador y hasta hay todo bien, mi problema es que al no saber programación no termino de aclararme y he empezado con cuatro pulsadores pero no hay manera o suma uno solo o en los cuatro suman a la vez o van correlativos, en fin haber si alguien me puede iluminar porque no se que hacer. Gracias
Este es el código que estoy trabajando

  // Importar librerías
  #include <Wire.h> // Librería comunicación I2C
  #include <LiquidCrystal_I2C.h> // Librería LCD I2C 
  LiquidCrystal_I2C lcd(0x27,20,4);
      

  const int pulsador = 2; // Entrada digital para el pulsador
  const int pulsador1 = 5; // Entrada digital para el pulsador
  const int pulsador2 = 6; // Entrada digital para el pulsador
  const int pulsador3 = 8; // Entrada digital para el pulsador
  const int tiempoAntirrebote = 50; // tiempo en ms para evitar el rebote
  int p;

  int p1;

  int p2;

  int p3;
  
  int cuenta = 0;
  int estadoBoton;
  int estadoBotonAnterior;
  



  
  // Función que evita el rebote del pulsador
  boolean antirrebote(int pin)
  {
    int contador = 0;
    boolean estado;
    boolean estadoAnterior;
    
    do
    {
      estado = digitalRead(pin);
      if(estado != estadoAnterior)
      {
        contador = 0;
        estadoAnterior = estado;
      }
      else
      {
        contador = contador+ 1;
      }
      delay(1);
    } while(contador < tiempoAntirrebote);
    
    return estado;
  }
    
        
  void setup() 
  {
    Serial.begin(9600);
    lcd.begin(20,4);   // Inicializa el LCD para 20x4  
    lcd.backlight(); // LED de fondo encendido (backlight)
    lcd.init(); 
   
    pinMode(pulsador, INPUT); // PIN digital del pulsador como entrada

    pinMode(pulsador1, INPUT); // PIN digital del pulsador como entrada

    pinMode(pulsador2, INPUT); // PIN digital del pulsador como entrada
   
    pinMode(pulsador3, INPUT); // PIN digital del pulsador como entrada
    
    
    // Presentamos datos por el LCD
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Pulsaciones:  ");
    lcd.setCursor(0,1);
    lcd.print("Pulsaciones:  ");
    lcd.setCursor(0,2);
    lcd.print("Pulsaciones:  ");
    lcd.setCursor(0,3);
    lcd.print("Pulsaciones:  ");
   }
  
  void loop() 
  {  
    p=estadoBoton = digitalRead(pulsador);
    
    if(estadoBoton != estadoBotonAnterior)
    {
      if(antirrebote(pulsador))
      {
      cuenta++;
        lcd.setCursor(13,0);
        lcd.print(cuenta);  // Se muestra a través del LCD el nº de veces que presionamos el pulsador
     }   
   }  
        estadoBotonAnterior = estadoBoton;
        
        


  {  
    p1=estadoBoton = digitalRead(pulsador1);
    
    if(estadoBoton != estadoBotonAnterior)
    {
      if(antirrebote(pulsador1))
      {
      cuenta++;
        lcd.setCursor(13,1);
        lcd.print(cuenta);  // Se muestra a través del LCD el nº de veces que presionamos el pulsador
     }   
   }  
        estadoBotonAnterior = estadoBoton;
       
       
       
         {  
    p2=estadoBoton = digitalRead(pulsador2);
    
    if(estadoBoton != estadoBotonAnterior)
    {
      if(antirrebote(pulsador2))
      {
      cuenta++;
        lcd.setCursor(13,2);
        lcd.print(cuenta);  // Se muestra a través del LCD el nº de veces que presionamos el pulsador
     }   
   }  
        estadoBotonAnterior = estadoBoton;
        
        
        
        
          {  
    p3=estadoBoton = digitalRead(pulsador3);
    
    if(estadoBoton != estadoBotonAnterior)
    {
      if(antirrebote(pulsador3))
      {
      cuenta++;
        lcd.setCursor(13,3);
        lcd.print(cuenta);  // Se muestra a través del LCD el nº de veces que presionamos el pulsador
     }   
   }  
        estadoBotonAnterior = estadoBoton;
       }
       }
       }
       }

Yo, sinceramente, no he entendido lo que quieres que haga tu programa. ¿Quieres una cuenta que incremente al pulsar cualquiera de los botones o cuatro cuentas independientes para cada uno de los cuatro botones?

Hola gracias por contestar, lo que quiero es que al pulsar cada pulsador cuente independientemente uno de otro y se refleje en la pantalla, en este código eh puesto cuatro pulsadores pero en verdad el proyecto es para 12 pulsadores y que vayan contando individual cada uno que si pulso el tercer botón cuente solo ese y los otros se mantengan como estén y la R seria como el reset de cada lado. No se si te eh aclarado lo que quiero seria algo asi.

Pues mucho más claro ahora, la verdad. Es cierto que vale más una imagen que mil palabras :wink:
Creo que lo mejor que puedes hacer es un array de estructuras con los botones y contadores. El propio recorrido del array puede hacer de antirebote.

Este código compila, aunque está sin probar. Mira a ver si te puede servir de ayuda:

struct {
	byte pinBoton;
	byte numPulsaciones;
	bool ultimoEstado;
} contador [12] = {
	{2, 0, LOW},
	{3, 0, LOW},
	{4, 0, LOW},
	{5, 0, LOW},
	{6, 0, LOW},
	{7, 0, LOW},
	{8, 0, LOW},
	{9, 0, LOW},
	{10, 0, LOW},
	{11, 0, LOW},
	{12, 0, LOW},
	{13, 0, LOW}
};

void setup(){
	for (int i=0; i<12; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
}

void loop(){
	for (int i=0; i<12; i++) {
		bool lectura=digitalRead(contador[i].pinBoton);
		if (lectura!=contador[i].ultimoEstado) {
			if (lectura==HIGH) {
				Serial.print("Contador ");
				Serial.print(i);
				Serial.print("=");
				Serial.println(++contador[i].numPulsaciones);
			}
			contador[i].ultimoEstado=lectura;
		}
	}
}

Muchas gracias no se como lo habrás hecho pero no tiene nada que ver con el que yo estaba trabajando pero lo veo perfecto lo que has diseñado y parece que funcionar bastante bien a falta de algunas cosillas todavía, una de ellas que estoy viendo haber el porque es que al llegar al 255 vuelve a cero y yo necesito que llegue al 9999, si me puedes decir el porque puede pasar esto y si tiene alguna solución. Gracias

El tipo de datos byte admite valores desde 0 a 255. Cambia byte numPulsaciones por unsigned int numPulsaciones y admitirá hasta 65535.

Lo que hizo noter esta perfecto. X botones que suman tus contadores.
Si no tiene nada que ver, entonces explicate mejor.
Que debe hacer cada pulsador, da ejemplo y no deja dudas. Y por otro lado, con lo que te sugierió noter, tu ya podrias trabajar por tu cuenta y darle mas sentido a lo que esperas que haga.

Muchas gracias a todos vosotros la verdad que ese cambio de byte por unsigned int numPulsaciones es lo que necesitaba muchas gracias de nuevo, voy a seguir con el inventillo a ver que tal sale y cuando lo tenga si no hay ningún problemilla más lo muestro por aquí como a quedado

La técnica de programación que hemos utilizado aquí (array de estructuras) es una muy buena base para muchísimos programas, y además es muy flexible: por ejemplo, podrías agregar dos variables más a la estructura (x e y) en las que indicas en qué coordenadas del LCD se va a imprimir su contador, o cualquier otra cosa que se te pueda ocurrir que deba llevar cada contador.
Y además es una buena puerta de entrada a la Programación Orientada a Objetos (de hecho una clase es básicamente una estructura de datos y funciones que trabajan con ellos).

Hola noter, perdona que te vuelva a molestar, pero veo que no se nada de programación, ni buscando en libros ni nada, porque no encuentro la manera de solucionar lo que quiero hacer, te dejo una foto de lo que quiero, por si sirve mas de aclaración. Lo que quiero hacer es que los doce botones o números que salen en pantalla se mantengan en ella y solo cambien a la ultima pulsación que haga en el botón de los doce que hay, pero siempre en orden los doce botones eje: si pulso el botón 4 del lado izquierdo y marca 1235 pues que ponga 1236, pero que todos los demás marque cada uno lo que lleva la ultima vez que se pulsaron sin moverse de su orden. Este es el código que mas o menos e modificado pero claro siempre marca el ultimo que eh marcado solo en una línea, y de ay no paso por mas vueltas que de. Aunque se que la pantalla es de 20x4 líneas tengo pedida una de Lcd 128x64 que es la que utilizaría. Muchas gracias de antemano por tu interés.

// Importar librerías
  #include <Wire.h> // Librería comunicación I2C
  #include <LiquidCrystal_I2C.h> // Librería LCD I2C 
  LiquidCrystal_I2C lcd(0x27,20,4);
struct {
 unsigned int pinBoton;
 unsigned int numPulsaciones;
 bool ultimoEstado;
} contador [12] = {
 {2, 0, LOW},
        {3, 0, LOW},
 {4, 0, LOW},
 {5, 0, LOW},
        {6, 0, LOW},
        {7, 0, LOW},
 {8, 0, LOW},
        {9, 0, LOW},
        {10,0, LOW},
 {11,0, LOW},
 {12,0, LOW},
 {13,0, LOW}
};
void setup(){
    Serial.begin(9600);
          lcd.begin(20,4);   // Inicializa el LCD para 20x4  
          lcd.backlight(); // LED de fondo encendido (backlight)
          lcd.init(); 
                 for (int i=0; i<12; i++) {
                 pinMode(contador[i].pinBoton, INPUT);
 }
}
void loop(){
 for (int i=0; i<12; i++) {
 bool lectura=digitalRead(contador[i].pinBoton);
 if (lectura!=contador[i].ultimoEstado) {
 if (lectura==HIGH) {
                            lcd.clear();
                            lcd.setCursor(0,0);
                            
                            lcd.print("");
    lcd.print(i);
    lcd.print(": ");
    lcd.print(++contador[i].numPulsaciones);
 }
 contador[i].ultimoEstado=lectura;
 }
 }
}

Mira a ver algo así, aunque deberás ajustar tu función muestraLCD a las características de tu pantalla (éste está sin probar). Como información, para que puedas entender el código, el operador % es el operador módulo o resto de la división.

#include <LiquidCrystal.h>
// Importar librerías
#include <Wire.h> // Librería comunicación I2C
#include <LiquidCrystal_I2C.h> // Librería LCD I2C
LiquidCrystal_I2C lcd(0x27,20,4);
struct {
	unsigned int pinBoton;
	unsigned int numPulsaciones;
	bool ultimoEstado;
} 
contador [12] = {
	{2, 0, LOW},
	{3, 0, LOW},
	{4, 0, LOW},
	{5, 0, LOW},
	{6, 0, LOW},
	{7, 0, LOW},
	{8, 0, LOW},
	{9, 0, LOW},
	{10,0, LOW},
	{11,0, LOW},
	{12,0, LOW},
	{13,0, LOW}
};



void setup(){
	Serial.begin(9600);
	lcd.begin(20,4);   // Inicializa el LCD para 20x4  
	lcd.backlight(); // LED de fondo encendido (backlight)
	lcd.init();
	for (int i=0; i<12; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
	muestraLCD();
}

void loop(){
	for (int i=0; i<12; i++) {
		bool lectura=digitalRead(contador[i].pinBoton);
		if (lectura!=contador[i].ultimoEstado) {
			if (lectura==HIGH) {
				++contador[i].numPulsaciones;
				muestraLCD();
			}
			contador[i].ultimoEstado=lectura;
		}
	}
}

void muestraLCD(void){
	char myBuff[7];
	for (int i=0; i<12; i++) {
		sprintf(myBuff, "%d:%04d", i, contador[i].numPulsaciones);
		lcd.setCursor(i/4, (i % 4) * 7);
		lcd.print(myBuff);
	}
}

Bueno he cambiado todo lo que se me ha ocurrido pero no hay manera de conseguir que salga todo en la pantalla he reducido a ocho pulsadores para que quede completa la pantalla de 20x4 pero no a habido manera tampoco así se me queda como se ve en la imagen, si podéis ayudarme para que quede el 0,1,2,3 en el lado izquierdo y el 4,5,6,7 en el lado derecho esto seria provisionar porque se supone que con la pantalla de 128x64 que estoy esperando cojera todo bien, lo que supongo que me dará otros muchos problemas por lo diferente que es con la LCD 20x4 espero que me puedan ayudar. Gracias

#include <LiquidCrystal.h>
// Importar librerías
#include <Wire.h> // Librería comunicación I2C
#include <LiquidCrystal_I2C.h> // Librería LCD I2C
LiquidCrystal_I2C lcd(0x27,20,4);
struct {
	unsigned int pinBoton;
	unsigned int numPulsaciones;
	bool ultimoEstado;
} 
contador [8] = {
	
        {22, 0, LOW},
	{24, 0, LOW},
	{26, 0, LOW},
	{28, 0, LOW},
	{30, 0, LOW},
	{32, 0, LOW},
	{34, 0, LOW},
	{36, 0, LOW}
};



void setup(){
	Serial.begin(9600);
	lcd.begin(20,4);   // Inicializa el LCD para 20x4  
	lcd.backlight(); // LED de fondo encendido (backlight)
	lcd.init();
	for (int i=0; i<8; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
	muestraLCD();
}

void loop(){
	for (int i=0; i<8; i++) {
		bool lectura=digitalRead(contador[i].pinBoton);
		if (lectura!=contador[i].ultimoEstado) {
			if (lectura==HIGH) {
				++contador[i].numPulsaciones;
				muestraLCD();
			}
			contador[i].ultimoEstado=lectura;
		}
	}
}

void muestraLCD(void){
	char myBuff[7];
	for (int i=0; i<8; i++) {
		sprintf(myBuff, "%d:%04d", i, contador[i].numPulsaciones);
		lcd.setCursor(i/4, (i % 5)*1);
		lcd.print(myBuff);
	}
}

Prueba con esto

#include <LiquidCrystal.h>
#include <Wire.h> 					// Librería comunicación I2C
#include <LiquidCrystal_I2C.h> 		// Librería LCD I2C

LiquidCrystal_I2C lcd(0x27,20,4);

struct {
	unsigned int pinBoton;
	unsigned int numPulsaciones;
	bool ultimoEstado;
} 

contador[8] = { {22, 0, LOW},
		{24, 0, LOW},
		{26, 0, LOW},
		{28, 0, LOW},
		{30, 0, LOW},
		{32, 0, LOW},
		{34, 0, LOW},
		{36, 0, LOW}
};


void setup(){
	Serial.begin(9600);
	lcd.begin(20,4);   // Inicializa el LCD para 20x4  
	lcd.backlight(); // LED de fondo encendido (backlight)
	lcd.init();
	for (int i=0; i<8; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
	muestraLCD();
}

void loop(){
	for (int i=0; i<8; i++) {
		bool lectura = digitalRead(contador[i].pinBoton);
		if (lectura != contador[i].ultimoEstado) {
			if (lectura == HIGH) {
				++contador[i].numPulsaciones;
				muestraLCD();
			}
			contador[i].ultimoEstado = lectura;
		}
	}
}

void muestraLCD(void){
	char myBuff[20];
	for (int i=0; i<4; i++) {
		sprintf(myBuff, "%02d:%04d  %02d:%04d", i, contador[i].numPulsaciones, i+4, contador[i+4].numPulsaciones);
		lcd.setCursor(i, 0);
		lcd.print(myBuff);
	}
}

Tal vez te funcione la primera versión (incluso para los doce pulsadores), pero con una ligera corrección:

void muestraLCD(void){
	char myBuff[7];
	for (int i=0; i<12; i++) {
		sprintf(myBuff, "%d:%04d", i, contador[i].numPulsaciones);
		lcd.setCursor(i/3, (i % 3) * 7); //puse 4 en lugar de 3, que es el número de columnas de pulsador que caben
		lcd.print(myBuff);
	}
}

Buenas noter he estado dándole vueltas a lo que me has puesto y no hay manera de que salgan bien los números no se porque salen todos revueltos,lo único que he conseguido con lo que puso surbyte y algunos cambios mas es que salgan bien con 8 pulsadores, te dejo imagen para que veas que salen bien pero solo con 8 como ponga 9 ya no hay manera. Ah te dejo para que veas la segunda y tercera imagen es lo que quiero sustituir por esto. Una pregunta, todo esto lo estoy haciendo con arduino mega para reducirlo al máximo quiero comprar el Arduino nano te dejo imagen y me gustaría la pantalla de 128x64. Crees que tendré algún problema tenéis alguna otra opción mejor??.
Gracias

#include <LiquidCrystal.h>
#include <Wire.h> 					// Librería comunicación I2C
#include <LiquidCrystal_I2C.h> 		// Librería LCD I2C

LiquidCrystal_I2C lcd(0x27,20,4);

struct {
	unsigned int pinBoton;
	unsigned int numPulsaciones;
	bool ultimoEstado;
} 

contador[8] = { {32, 0, LOW},
		{34, 0, LOW},
		{36, 0, LOW},
		{38, 0, LOW},
		{40, 0, LOW},
		{42, 0, LOW},
		{44, 0, LOW},
		{46, 0, LOW}
};


void setup(){
	Serial.begin(9600);
	lcd.begin(20,4);   // Inicializa el LCD para 20x4  
	lcd.backlight(); // LED de fondo encendido (backlight)
	lcd.init();
	for (int i=0; i<8; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
	muestraLCD();
}

void loop(){
	for (int i=0; i<8; i++) {
		bool lectura = digitalRead(contador[i].pinBoton);
		if (lectura != contador[i].ultimoEstado) {
			if (lectura == HIGH) {
				++contador[i].numPulsaciones;
				muestraLCD();
			}
			contador[i].ultimoEstado = lectura;
		}
	}
}

void muestraLCD(void){
	char myBuff[80];
	for (int i=0; i<4; i++) {
		sprintf(myBuff, "%d:%04d        %d:%04d", i, contador[i].numPulsaciones, i+4, contador[i+4].numPulsaciones);
		lcd.setCursor(i/4,(i%4));
		lcd.print(myBuff);
	}
}

La pantalla que ahora luce bien, con el código de noter que he modificado levemente no funciona como esperas.
Si te comprendo bien, cuando pulsas el pulsador 3, no se ve el incremento en el contador.

void loop(){
        char buf[20]; 
        for (int i=0; i<8; i++) {
              bool lectura = digitalRead(contador[i].pinBoton);
              if (lectura != contador[i].ultimoEstado) {
                 sprintf(buf, "puls : %d estado: %s", i, lectura?"ON":"OFF");
                 Serial.println(buf);
                 if (lectura == HIGH) {
                     ++contador[i].numPulsaciones;
                      muestraLCD();
                 }
                  contador[i].ultimoEstado = lectura;
              }
       }
}

void muestraLCD(void){
 char myBuff[20];
 for (int i=0; i<4; i++) {
 sprintf(myBuff, "%02d:%04d  %02d:%04d", i, contador[i].numPulsaciones, i+4, contador[i+4].numPulsaciones);
 lcd.setCursor(i, 0);
 lcd.print(myBuff);
 }
}

Veamos con este código que ocurre con los pulsadores.
Tengo sospechas que rebotan.

Exactamente, empiezan a contar solos :o es tocar el cable y empiezan a contar. :’( :’( :’( :’(
Para que salgan bien en pantalla tengo que cambiar algunas cosas aquí ves lo que modifico para que salga bien en pantalla

void loop(){
        char buf[20]; 
        for (int i=0; i<8; i++) {
              bool lectura = digitalRead(contador[i].pinBoton);
              if (lectura != contador[i].ultimoEstado) {
                 sprintf(buf, "puls : %d estado: %s", i, lectura?"ON":"OFF");
                 Serial.println(buf);
                 if (lectura == HIGH) {
                     ++contador[i].numPulsaciones;
                      muestraLCD();
                 }
                  contador[i].ultimoEstado = lectura;
              }
       }
}

void muestraLCD(void){
 char myBuff[80];
 for (int i=0; i<4; i++) {
 sprintf(myBuff, "%02d:%04d      %02d:%04d", i, contador[i].numPulsaciones, i+4, contador[i+4].numPulsaciones);
 lcd.setCursor(i/4,(i%4));
 lcd.print(myBuff);
 }
}

Que se puede hacer para que no pase eso de contar solo

El código que propuse era para imprimir en tres columnas, en lugar de en dos (entraría justo, pero entrarían los doce contadores). Lo que pasa es que como no tengo esa pantalla para probar, no sé el efecto que se produce. Tal vez he invertido filas y columnas en el lcd.setCursor(i/4, (i % 4) * 7) y debiera ser lcd.setCursor((i % 3) * 7, i/3), aunque también se podrían imprimir las tres columnas con el sistema de surbyte.

Yo lo pense @noter pero daban pegados.
Tenes 6 para las dos primeras y 7 para la ultima columna de 9 10 11 y 12 que son XX:0000
12+7 = 19 y te faltan 2 caracteres para separar
Para mi no va.
Ahora no entiendo que es lo que no le funciona. El código que propusiste Serafín (@noter) está perfecto, salvo que haya rebotes.

Buenas surbyte, quería decirte que con este código que pongo aquí abajo va todo bien no hay ningún problema, era comentar que solo va bien con 8, lo que si tiene es rebote. Por lo demás todo bien

#include <LiquidCrystal.h>
#include <Wire.h> 					// Librería comunicación I2C
#include <LiquidCrystal_I2C.h> 		// Librería LCD I2C

LiquidCrystal_I2C lcd(0x27,20,4);

struct {
	unsigned int pinBoton;
	unsigned int numPulsaciones;
	bool ultimoEstado;
} 

contador[8] = { {32, 0, LOW},
		{34, 0, LOW},
		{36, 0, LOW},
		{38, 0, LOW},
		{40, 0, LOW},
		{42, 0, LOW},
		{44, 0, LOW},
		{46, 0, LOW}
};


void setup(){
	Serial.begin(9600);
	lcd.begin(20,4);   // Inicializa el LCD para 20x4  
	lcd.backlight(); // LED de fondo encendido (backlight)
	lcd.init();
	for (int i=0; i<8; i++) {
		pinMode(contador[i].pinBoton, INPUT);
	}
	muestraLCD();
}

void loop(){
	for (int i=0; i<8; i++) {
		bool lectura = digitalRead(contador[i].pinBoton);
		if (lectura != contador[i].ultimoEstado) {
			if (lectura == HIGH) {
				++contador[i].numPulsaciones;
				muestraLCD();
			}
			contador[i].ultimoEstado = lectura;
		}
	}
}

void muestraLCD(void){
	char myBuff[80];
	for (int i=0; i<4; i++) {
		sprintf(myBuff, "%d:%04d        %d:%04d", i, contador[i].numPulsaciones, i+4, contador[i+4].numPulsaciones);
		lcd.setCursor(i/4,(i%4));
		lcd.print(myBuff);
	}
}

Gracias