Juego de Luces para Arduino con leds, pulsador y display

Hola chicos, estoy intentando hacer un proyecto con un display, 7 leds y un boton. Lo que tiene que hacer el juego es los leds tienen que parpadear continuamente y el led del medio tiene que ser verde. y los demás rojos. por ejemplo si estan desde el pin 7-13 el 10 es el led verde. Entonces cuando tu presiones el boton y la luz que este encendida sea la verde en tu display suma un numero, y siguen parpadeando. Si por otro lado pulsas el boton cuando hay uno rojo se reinicia el contador. solo necesito los contadores d1 y d2. A ver si alguien me puede ayudar. Muchas gracias!! He conseguido implementar el tema de las luces, pero el display no me funciona.

/ Librería Timer
#include "Timer.h"

// Pines
const int BUTTON_PIN = 2;
const int NUM_LEDS = 5;
const int LED_PINS[] = {12, 11, 10, 9, 8};
const int SEGMENT_PINS[] = {A5, A3, 4, 5, 6, A4, 3};
const int DIGIT_PINS[] = {A1, A2};

// Variables globales
int ledState = 0;
int direction = 1;
bool buttonPressed = false;
bool buttonLastState = HIGH;
bool gameActive = true;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

int score = 0;

// Configuración
void setup()
{
// Configura botón y LEDs
pinMode(BUTTON_PIN, INPUT_PULLUP);

for (int i = 0; i < NUM_LEDS; i++)
{
pinMode(LED_PINS[i], OUTPUT);
}

// Configura display 7 segmentos
for (int i = 0; i < 7; i++)
{
pinMode(SEGMENT_PINS[i], OUTPUT);
}

for (int i = 0; i < 2; i++)
{
pinMode(DIGIT_PINS[i], OUTPUT);
}

// Inicializa Timer
TimerSet(100); // Ajusta el valor del temporizador a 100ms
TimerOn();

Serial.begin(9600); // Inicia la comunicación serie para mensajes de depuración
}

// Loop principal
void loop()
{
// Lee botón con debounce
int reading = digitalRead(BUTTON_PIN);

Serial.print("Button reading: ");
Serial.println(reading);

if (reading != buttonLastState)
{
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay)
{
if (reading != buttonPressed)
{
buttonPressed = reading;

  if (buttonPressed)
  {
    // Botón presionado, aumenta el puntaje si la LED verde está encendida
    if (ledState == 2 && gameActive)
    {
      score++;

      // Si el puntaje alcanza cierto valor, cambia a estado de juego inactivo
      if (score >= 10)
      {
        gameActive = false;

        // Enciende el LED rojo
        digitalWrite(LED_PINS[ledState], HIGH);
      }
    }
  }
}
}

buttonLastState = reading;

if (TimerFlag)
{
TimerFlag = 0;

// Imprime mensajes de depuración para verificar el estado de los LEDs y el temporizador
Serial.print("LED state: ");
Serial.println(ledState);

Serial.print("Game active: ");
Serial.println(gameActive);

Serial.print("Timer flag: ");
Serial.println(TimerFlag);

// Ejecuta máquinas de estado si el juego está activo
if (gameActive)
{
  ledSM();
  displaySM();
}
}
}

// Función máquina de estados para LEDs
void ledSM()
{
// Lógica de shifteo de LEDs
ledState += direction;

if (ledState == 0)
{
direction = 1;
}
else if (ledState == NUM_LEDS - 1)
{
direction = -1;
}

// Enciende LED
for (int i = 0; i < NUM_LEDS; i++)
{
digitalWrite(LED_PINS[i], i == ledState);
}
}

// Función máquina de estados para display
void displaySM()
{
static int refreshCounter = 0;

// Multiplexación de dígitos
int digit = refreshCounter % 2;
digitalWrite(DIGIT_PINS[0], digit == 0);
digitalWrite(DIGIT_PINS[1], digit == 1);

// Muestra puntaje en dígito
if (digit == 0)
{
displayNumber(score / 10, 0);
}
else
{
displayNumber(score % 10, 1);
}

refreshCounter++;
}

// Función para mostrar número en dígito
void displayNumber(int number, int digit)
{
const byte SEGMENT_MAP[] = {B11000000, B11111001, B10100100, B10110000, B10011001, B10010010, B10000010, B11111000, B10000000, B10010000};

byte displayValue = SEGMENT_MAP[number];

for (int i = 0; i < 7; i++)
{
digitalWrite(SEGMENT_PINS[i], displayValue & (1 << i));
}

digitalWrite(DIGIT_PINS[digit], LOW); // Habilita dígito
}

Please post in English in the English language forum sections.

Muéstranos tu código para ver en qué te apoyamos

He trasladado su tema de una categoría de idioma inglés del foro a la categoría International > Español @allguti24.

En adelante por favor usar la categoría apropiada a la lengua en que queráis publicar. Esto es importante para el uso responsable del foro, y esta explicado aquí la guía "How to get the best out of this forum".
Este guía contiene mucha información útil. Por favor leer.

De antemano, muchas gracias por cooperar.

// Librería Timer
#include "Timer.h"

// Pines
const int BUTTON_PIN = 2;
const int NUM_LEDS = 5;
const int LED_PINS[] = {12, 11, 10, 9, 8};
const int SEGMENT_PINS[] = {A5, A3, 4, 5, 6, A4, 3};
const int DIGIT_PINS[] = {A1, A2};

// Variables globales
int ledState = 0;
int direction = 1;
bool buttonPressed = false;
bool buttonLastState = HIGH;
bool gameActive = true;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

int score = 0;

// Configuración
void setup()
{
// Configura botón y LEDs
pinMode(BUTTON_PIN, INPUT_PULLUP);

for (int i = 0; i < NUM_LEDS; i++)
{
pinMode(LED_PINS[i], OUTPUT);
}

// Configura display 7 segmentos
for (int i = 0; i < 7; i++)
{
pinMode(SEGMENT_PINS[i], OUTPUT);
}

for (int i = 0; i < 2; i++)
{
pinMode(DIGIT_PINS[i], OUTPUT);
}

// Inicializa Timer
TimerSet(100); // Ajusta el valor del temporizador a 100ms
TimerOn();

Serial.begin(9600); // Inicia la comunicación serie para mensajes de depuración
}

// Loop principal
void loop()
{
// Lee botón con debounce
int reading = digitalRead(BUTTON_PIN);

Serial.print("Button reading: ");
Serial.println(reading);

if (reading != buttonLastState)
{
lastDebounceTime = millis();
}

if ((millis() - lastDebounceTime) > debounceDelay)
{
if (reading != buttonPressed)
{
buttonPressed = reading;

  if (buttonPressed)
  {
    // Botón presionado, aumenta el puntaje si la LED verde está encendida
    if (ledState == 2 && gameActive)
    {
      score++;

      // Si el puntaje alcanza cierto valor, cambia a estado de juego inactivo
      if (score >= 10)
      {
        gameActive = false;

        // Enciende el LED rojo
        digitalWrite(LED_PINS[ledState], HIGH);
      }
    }
  }
}

}

buttonLastState = reading;

if (TimerFlag)
{
TimerFlag = 0;

// Imprime mensajes de depuración para verificar el estado de los LEDs y el temporizador
Serial.print("LED state: ");
Serial.println(ledState);

Serial.print("Game active: ");
Serial.println(gameActive);

Serial.print("Timer flag: ");
Serial.println(TimerFlag);

// Ejecuta máquinas de estado si el juego está activo
if (gameActive)
{
  ledSM();
  displaySM();
}

}
}

// Función máquina de estados para LEDs
void ledSM()
{
// Lógica de shifteo de LEDs
ledState += direction;

if (ledState == 0)
{
direction = 1;
}
else if (ledState == NUM_LEDS - 1)
{
direction = -1;
}

// Enciende LED
for (int i = 0; i < NUM_LEDS; i++)
{
digitalWrite(LED_PINS[i], i == ledState);
}
}

// Función máquina de estados para display
void displaySM()
{
static int refreshCounter = 0;

// Multiplexación de dígitos
int digit = refreshCounter % 2;
digitalWrite(DIGIT_PINS[0], digit == 0);
digitalWrite(DIGIT_PINS[1], digit == 1);

// Muestra puntaje en dígito
if (digit == 0)
{
displayNumber(score / 10, 0);
}
else
{
displayNumber(score % 10, 1);
}

refreshCounter++;
}

// Función para mostrar número en dígito
void displayNumber(int number, int digit)
{
const byte SEGMENT_MAP[] = {B11000000, B11111001, B10100100, B10110000, B10011001, B10010010, B10000010, B11111000, B10000000, B10010000};

byte displayValue = SEGMENT_MAP[number];

for (int i = 0; i < 7; i++)
{
digitalWrite(SEGMENT_PINS[i], displayValue & (1 << i));
}

digitalWrite(DIGIT_PINS[digit], LOW); // Habilita dígito
}
Tengo esto, he conseguido implementar las luces pero el tema del display no

Hi guys, I'm trying to make a project with a display, 7 LEDs and a button. What the game has to do is the LEDs have to flash continuously and the middle LED has to be green. and the rest red. For example, if they are from pin 7-13, 10 is the green LED. So when you press the button and the green light on your display adds a number, and they continue flashing. If, on the other hand, you press the button when there is a red one, the counter is reset. I only need the d1 and d2 counters. Let's see if someone can help me. Thank you so much!!

Creo que esto debería ser

digitalWrite(SEGMENT_PINS[i], (displayValue >> i) & 1);

he cambiado la linea pero sigue sin ir

displaySM() pone a HIGH el dígito que selecciona y deja el otro en LOW

Más adelante, con esta instrucción displayNumber() apaga el dígito que debe mostrar

Creo que esta instrucción no va. Coméntala y dinos qué sucede

se me encienden unicamente dos segmentos del display de las leds, el del medio y el segmento superior a la derecha, estan parpadeando todo el rato

¿Puedes mostrar un dibujo de cómo está conectado tu circuito?



Cuál es el número de parte del display que estás utilizando?

Está mal conectado el display.
En el código usas el pin A1 y en la foto se ve que A1 está libre, y has conectado A0 en su lugar.
Mueve el cable rojo a la posición correcta.

El botón está conectado a un pin que no corresponde al sketch

Aparte de lo que notó @mancera1979 , el botón esta mal conectado "a secas".

El pin 2 tiene activada la resistencia pull-up, entonces no sería necesario conectar el pulsador a 5V ni tampoco llevaría la resistencia conectada a GND (no sería necesaria).

Además, salvo que la foto "engañe", el botón nunca cambiará de estado porque está conectado a los pines que internamente están unidos por lo que siempre se leerá HIGH.

Según me parece, estaría conectado así, y claramente está mal

Probablemente si en lugar de las fotos hubieses hecho el esquema, como te pidió @mancera1979 , te habrías dado cuenta de los errores.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.