Arma Láser con chalecos

Hola. espero estar preguntando en el lugar correcto. Paso a explicar, estoy queriendo hacer para mis chicos un juego de esos de arma laser con chalecos.
Viendo y recopilando info por varias paginas y tutoriales logre hacer un código, no es lo esperado pero para una primer versión me conformo.
Cabe aclarar que es la primera vez que hago esto, siempre fue ver y copiar algunos proyectos de los miles que hay en Internet.

Bueno el código en una primer etapa es el arma, la cual tiene un led IR o Laser de disparo y 9 leds que representan las municiones.
Al pulsador le puse antirrebote para que solo cuente cuando suelto el pulsador, pero esto causa que el led laser quede encendido.

Lo ideal seria que por mas pulsado el botón el led con un delay de un segundo e apague. Oh la otra opción es que si mantienes apretado el pulsador gaste municiones.

int irled = 12;
int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int led7 = 8;
int led8 = 9;
int led9 = 10;
int tiro = 0;
int contador = 0;
int estadoCero = 0;
int boton = 0;

void setup() {
  Serial.begin(9600);
  pinMode(irled, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led1, OUTPUT);

  pinMode(boton, INPUT);
}

void loop() {
  tiro = digitalRead(0);
  if (tiro == HIGH) {
    digitalWrite (irled, HIGH);
  }
  else {
    digitalWrite(irled, LOW);
  }
  int  pl = digitalRead(boton);
  if (pl != estadoCero) {
    if (pl == HIGH)
    {
      contador++;
      Serial.println(contador);
    }
  }
  estadoCero = pl;
  if (contador == 1) {
    digitalWrite(led1, HIGH);
  }
  if (contador == 2) {
    digitalWrite(led2, HIGH);
  }
  if (contador == 3) {
    digitalWrite(led3, HIGH);
  }
  if (contador == 4) {
    digitalWrite(led4, HIGH);
  }
  if (contador == 5) {
    digitalWrite(led5, HIGH);
  }
  if (contador == 6) {
    digitalWrite(led6, HIGH);
  }
  if (contador == 7) {
    digitalWrite(led7, HIGH);
  }
  if (contador == 8) {
    digitalWrite(led8, HIGH);
  }
  if (contador == 9) {
    digitalWrite(led9, HIGH);
  }
  if (contador == 10) {
    digitalWrite(irled, LOW);
    delay(1000);

    digitalWrite(led9, LOW);
    delay(200);

    digitalWrite(led8, LOW);
    delay(300);

    digitalWrite(led7, LOW);
    delay(400);

    digitalWrite(led6, LOW);
    delay(500);

    digitalWrite(led5, LOW);
    delay(600);

    digitalWrite(led4, LOW);
    delay(800);

    digitalWrite(led3, LOW);
    delay(900);

    digitalWrite(led2, LOW);
    delay(950);

    digitalWrite(led1, LOW);
    delay(900);

    contador = 0;
  }
}

Hola @RC772000, bienvenido al foro arduino.
He corregido tu título porque no era apropiado y también tu intento de poner la imagen que espero sea esta.

Para que el led no quede prendido lo que yo uso es preguntar por el estado anterior y disparar con los flancos.
En general no hace falta eliminar rebotes.

A ver como se comporta este código

const byte irled = 12;
const byte led1 = 2;
const byte led2 = 3;
const byte led3 = 4;
const byte led4 = 5;
const byte led5 = 6;
const byte led6 = 7;
const byte led7 = 8;
const byte led8 = 9;
const byte led9 = 10;
const byte boton = 0;

bool tiro;
bool  pl, plAnt;
int contador = 0;

void setup() {
  Serial.begin(9600);
  pinMode(irled, OUTPUT);
  pinMode(led9, OUTPUT);
  pinMode(led8, OUTPUT);
  pinMode(led7, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led1, OUTPUT);

  pinMode(boton, INPUT);
}

void loop() {
  tiro = digitalRead(0);
  if (tiro == HIGH) {
    digitalWrite (irled, HIGH);
  }
  else {
    digitalWrite(irled, LOW);
  }
 
  pl = digitalRead(boton);

  if (pl && !plAnt) {
      contador++;
      Serial.println(contador);
  }
  plAnt = pl;
  
  if (contador == 10) {
      digitalWrite(irled, LOW);
      delay(1000);
      for (int i=9; i>0; i--) {
          digitalWrite(i*1, LOW);
          delay((11-i)*100);  // comienza con 200 y se incrementa de a 100
      }
      contador = 0;
  }
  else {
      digitalWrite(contador+1, HIGH);
  }
}

He cambiado el pulsador del gatillo al pin analógico AO. No tienes que usar resistencia y lo conectas al pin y masa.

Este modelo de ametralladora lo llamaremos Rambo(II).

int irled = 12;
int button=A0;    // Usar pin analógico A0 sin resitencia y pulsador a masa.
int cont = 2;     
int recarga = 40; // tiempo de recarga por cada bala en milisegundos
int fogueo = 300;  //tiempo de encendido del laser en milisegundos
void setup() {
  pinMode(irled, OUTPUT);
  pinMode(button, INPUT_PULLUP);
  for (byte  a=2; a<11; a++){ pinMode(a, OUTPUT); digitalWrite(a,HIGH); }
}

void loop() {
  if (digitalRead(button) == LOW ) {
    delay(15);
    if (digitalRead(button) == LOW ) {
      
     digitalWrite(irled,HIGH);
      digitalWrite(cont,LOW);
      delay(fogueo);
      cont++;
      digitalWrite(irled,LOW);
      delay(100);
    }
  }
  if (cont > 10) { 
    cont = 2; 
    for (byte  a=2; a<11; a++){ digitalWrite(a,HIGH); delay(recarga);}
    }
}

Quiero una foto del modelo terminado.
Saludos

ArduMyth:
¿?¿?¿?¿?¿ ¿Por ser analógico dices que es innecesaria la resistencia? ¿O es por el pinMode con INPUT_PULLUP?

Cuando necesitas aclarar que no es un ataque, es porque te vienes con un ataque. Cuando necesitas aclarar que no es de ofensivo es porque a continuación lo serás. No aclares que oscurece.

En ningún momento le he dicho del porque no necesitar usar la resistencia. RC772000 usó el pin 0 digital para su gatillo, entonces lo he cambiado de lugar y listo.

Editado

Un delay de 15 entre dos lecturas de un botón sirve perfectamente para el caso. El arma no tiene que estar haciendo otro cálculo, es simplemente un arma. En un duelo entre mi debouce y el tuyo es la diferencia entre que tu termines muerto. Entiendo que un usuario con su primer post, viene en busca de una solución y no una clase de programación. Por tal motivo y como se me dio las ganas, le hago un código y sanseacabó.

Controlemos los comentarios fuera de lugar y con falta de respeto.

surbyte:
Controlemos los comentarios fuera de lugar y con falta de respeto.

¿A vos te parece educado decir? "harto repetido", "eres un cabeza dura", si lo haces así, entonces es porque no razonas, es una lacra ver que usas tanto delay....

Pero te parece mal guardar algo librado a la imaginación. ¡Vaya a saber cual es ese lugar has imaginado!

Daniel en muchos países de habla hispana se usa este "Harto repetido" para indicar muy repetido no tiene connotación con nuestro "harto".

"cabeza dura" no leo donde esta escrito salvo tu mención.

surbyte:
Daniel en muchos países de habla hispana se usa este "Harto repetido" para indicar muy repetido no tiene connotación con nuestro "harto".

"cabeza dura" no leo donde esta escrito salvo tu mención.

Es tema harto repetido que delay() no es un timer pero nada, siguen usándolo como tal y para todo.

¿Entonces yo no puedo imaginar que le dicen al usuario que es un cabeza dura, pero si tu puedes imaginar el lugar nunca expresado donde guardar un comentario? Tu sufres de indignación selectiva.

Terminado Daniel, no desvies el tema del hilo.
Esto si queres discutirlo lo seguis por privado.

RC772000:
estoy queriendo hacer para mis chicos un juego de esos de arma laser con chalecos.

Aquí te dejo el código comentado. Los disparos salen al instante de oprimir el gatillo.
Ahora hay 4 led's rojos para representar en binario las municiones que tiene el arma
Tres led's de otro color para indicar en binario las heridas recibidas. Cuando los tres led' apagan estas muerto.

Se puede recargar oprimiendo otro pulsador pero solo después de 5 segundos de hacer el último disparo.

Estos tiempos los puedes cambiar.

Creo que deberías usar algún led infrarrojo potente con una lente para concentrar el haz. El láser puede ser peligroso para el ojo humano.

Todavía quedan pines por si quieres implementar sonido o mas iluminación.

Suerte.

/*
 * Arduino pinout:
 *             _______________
 *            |      USB      |
 *            |13           12| Emiror infrarrojo.
 *            |3V3          11| 
 *            |AREF         10| led verde vida
 *            |              9| led verde vida
 *   button1  |A1            8| Led verde vida
 *   button2  |A2            7| led rojo munición
 *   sensor   |A3            6| led rojo munición
 *            |A4            5| led rojo munición
 *            |A5            4| led rojo munición
 *            |              3| 
 *            |              2| 
 *            |5V          GND|
 *            |RST         RST|
 *            |GND   1/INT2/RX|
 *            |VIN   0/INT3/TX|
 *            |MISO         SS|
 *            |SCK        MOSI|
 *            |_______________|
 *
*/

int irled = 12;     
int button1=A0;   // Sin resistencia y pulsador a masa.
int button2=A1;   // Sin resistencia y pulsador a masa.
int sensor= A2;     // Sensor IR
int heridas= 7;      // Cantidad de impactos recibidos para la muerte.
int Timpacto = 30;  // Tiempo de impacto, el sensor debe estar LOW mas de este tiempo para descontar una vida.  
int cont = 15;      // Municiones por recarga
int recarga = 5000; // tiempo de recarga en milisegundos
int fogueo = 200;  // tiempo de encendido del emisor infrarrojo en milisegundos

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long timeherida = 0;
void setup() {
 for (byte  a=4; a<13; a++){ pinMode(a, OUTPUT); digitalWrite(a,HIGH); }  
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(sensor,  INPUT_PULLUP);
}

void loop() {  
  
  while (heridas != 0) {
  currentMillis = millis();
  municion(cont);   // Muestra la municiones
  muestravidas(heridas);  // Muestra si nos hieren
  
  if (digitalRead(sensor) == LOW) {  // Si el sensor recibe un infrarrojo 
    timeherida = currentMillis;      // Toma el tiempo donde ha iniciado el infrarrojo
    while (digitalRead(sensor) == LOW) {  // Mientras se reciba el infrarrojo
     currentMillis = millis();           // Avanza con la cuenta del tiempo hasta dejar de recibir el infrarrojo
    }  
    if (currentMillis - timeherida > Timpacto) { // Si el tiempo de infrarrojo fue superior al Tiempo de impacto
    heridas--;   // Descuenta de la cantidad max. de heridas
    muestravidas(heridas);  // Actualiza el visor
    }
  }
  
    if (currentMillis - previousMillis > fogueo) {   //  Si el tiempo de fuego a pasado
     digitalWrite(irled,LOW); //  Apaga el emisor infrarrojo
     } 
    
    if (((digitalRead(button1) == LOW and (cont > 0 ))) and (currentMillis - previousMillis > fogueo*2)) { // si quedan balas y puedes volver a disparar
     previousMillis = currentMillis;
     digitalWrite(irled,HIGH);  //  Enciende laser
     digitalWrite(cont,HIGH);  // descuenta un tiro
     cont--;  // descuenta el contador     
    }   

    if ((cont == 0) and (currentMillis - previousMillis > recarga)) {  // SI te quedas sin balas y han pasado ya el tiempo necesario para recargar
      if (digitalRead(button2) == LOW) {  // Lee si pulsamos el botón para recargar
        cont = 15;   // Vuelve a cargar la municiones
      }
     } 
  }
  
  municion(0);  // Apaga las municiones si mueres

  previousMillis = millis();
  while (heridas == 0) {  //  Si llegaste a la muerte entonces puedes poner aqui encender led' del chaleco o revivir a los 10 minutos
   
    currentMillis = millis();
    if (currentMillis - previousMillis > 600000) {  //  Diez minutos en pagado
      heridas= 7; //  
      cont   = 15;
      
    }
    
  }
 
}

void municion( byte val) {
    int x=val; 
    for(int a=4; a<8; a++){ 
    digitalWrite(a, x%2); 
    x=x/2;
    }
}

void muestravidas( byte val) {
    int k=val; 
    for(int a=8; a<11; a++){ 
    digitalWrite(a, k%2); 
    k=k/2;
    }
}

¿Que culpa tiene el usuario que recién llega a este foro que tu le hayas regañado a cuanta persona use un delay?

Necesita un juguete para sus niños y no un profesor de programación.

El usuario ha hecho lo que pudo y como pudo, y eso para mi es suficiente como para que le dedique un tiempo en ayudarlo con lo poco que se.

Como dices, es un usuario nuevo y no tiene porque saber que este es el foro de los regaños. donde en lugar de dar una mano, están para decirles a los que recién entran y a los otros también, lo tonto que son por no saber hacer las cosas que tu consideras bien.

Si, entro en un bucle porque así quiero que funcione, porque mientras se recibe un disparo quiero que el arma no pueda hacer otra cosa. ¿porque no haces una queja a arduino para que eliminen delay y while?

¿Si consideras que no me gusta que me corrijan entonces porque lo haces?

¿Sabes que? tengo el compilador para que me advierta de algún error. No te necesito de profesor. No se entiende porque Bill Gates no te contrata.

Parece que la vida los trata muy mal y eligen desquitarse con todo aquel que llega a este foro.

En este hilo @Daniel_Arg y @ArduMyth no van a hacer ningún comentario mas.
1. En cuanto vea alguno será baneado 1 día por cada post que realice.
2. A ambos se le ha dicho que ninguno va a corregir al otro como para provocarlo. Del mismo modo si veo que alguno lo hace misma sanción.
Desde este momento ambos se van a ignorar y si no lo quieren hacer tendrán vacaciones forzadas.
No daré mas advertencias.

Muchísima gracias @Surbyte y A @Daniel_Arg Por tu ayuda. Y el código que Me pasaste funciona de maravilla además quedo mejor que inicien todo los led prendido, soy muy nuevo en esto de programar y lenguaje C++.

De seguro algún otro concejo y ayuda necesitare. Apenas tenga avances con la contracción de este proyecto subiré fotos.
Gracias.