Manipulación de 7 Segmentos en tablero deportivo

Hola, estoy realizando un proyecto donde debo mezclar algunas cosas y con las que no estoy muy familiarizado, quiero hacer un tanteador deportivo con arduino, en el borde superior del tablero iría el tiempo y debajo los marcadores de los dos equipos, además quiero controlar los puntos del equipo con solos dos botones, por lo que tendría que hacer alguna programación donde pueda borrar con el mismo botón que aumenta la cuenta, tengo pensado que dejándolo presionado unos 2 segundo capaz se pueda. La programación del reloj ya le tengo terminada y probada, hasta ahora marcha bien, el problema es como aumentar con el resto de la programación. Tengo un arduino uno atmel328 por lo que estoy bastante preocupado por las E/S digitales.....alguna ayuda por favor?
Muchas gracias.

Hola, ¿A que le llamas proyecto? Porque dicho de esa forma pareciera que debes hacer por lo menos el tanteador del club de la ciudad.

¿Tenis, futbol? porque no es lo mismo.

En la librería "OneButton" tienes un ejemplo con dos botones y por cada botón puedes usar la función click, doubleclick y LongPress con lo cual con el botón1 puedes sumar un tanto al equipo uno en la función click y descontar con doble click. Poner a Cero ambos tanteador con LongPress de cualquiera de los dos botones.

¿Que display estas usando?

Podrías usar el circuito integrado TM1637 que tiene la capacidad de controlar 6 dígitos y si fuera el tanteador de un estadio de futbol con dos dígitos podrías representar los 90 minutos que dura un partido.

Los otros cuatro dígitos restantes, dos para cada equipo por si alguno llegara a hacer 10 goles.

Por los pines no tienes problemas porque con solo dos se controla la pantalla.

Los TM1637 también vienen en módulos para arduino, pero con cuatro dígitos aunque el integrado tenga capacidad para seis.

No olvides subir tu código, aunque el proyecto sea solo un ejercicio de aprendizaje.

Saludos

Hola, soy novato en este mundo y estoy terminando un proyecto para un tablero deportivo donde tengo que controlar 6 display 7 segmentos, dos muestran el tiempo de duración del partido (60 minutos) y dos para los puntos de cada equipo, además de marcar con dos botones también puedo borrar los puntos si los dejo presionado 1500 ms, el problema que tengo es que el 7 segmentos que me muestra las decenas en el tiempo me está dibujando el segmento g de ese display cuando no debería, uso arduino uno atmega328 con dos ULN2803, desde ya muchas gracias por sus comentarios.

Acá esta la rutina que uso.

//DEFINICIONES.
#define boton_1 10
#define boton_2 9
#define boton_start 11

//DECLARACION DE VARIABLES.
int retardo = 1;     // tiempo que dura encendido cada 7 seg (1 mili segundos)
int estado;


const int ESTADO_STOP = 0;
const int ESTADO_START = 1;
const int ESTADO_FIN = 2;

unsigned long tiempoPasado = 0;
unsigned long tiempoInicio = 0;
unsigned long tiempoPulsador1Presionado;
unsigned long tiempoPulsador2Presionado;

boolean cero[] = {1, 1, 1, 1, 1, 1, 0};
boolean uno[] = {0, 1, 1, 0, 0, 0, 0};
boolean dos[] = {1, 1, 0, 1, 1, 0, 1};
boolean tres[] = {1, 1, 1, 1, 0, 0, 1};
boolean cuatro[] = {0, 1, 1, 0, 0, 1, 1};
boolean cinco[] = {1, 0, 1, 1, 0, 1, 1};
boolean seis[] = {1, 0, 1, 1, 1, 1, 1};
boolean siete[] = {1, 1, 1, 0, 0, 0, 0};
boolean ocho[] = {1, 1, 1, 1, 1, 1, 1};
boolean nueve[] = {1, 1, 1, 0, 0, 1, 1};

byte pinSeg[] = {2, 3, 4, 5, 6, 7, 8};//esta matriz contiene el valor de cada pin digital conectado a {a,b,c,d,e,f,g} del 7segmento
byte showDig[] = {A0, A1, A2, A3, A4, A5};//cada una de estas salidas en para activar cada digito [multiplexado].
int valor[6]; //En esta matriz almaceno el valor de cada digito del 7segmento

const int tiempoAntirebote = 10;



int pulsador_1;
int estadoPulsadorAnterior_1 = 1;
int pulsador_2;
int estadoPulsadorAnterior_2 = 1;
int pulsador_start;
int estadoPulsadorAnterior_start;

int puntosLocal = 0;
int puntosVisita = 0;


void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 8; i++) {
    pinMode(pinSeg[i], OUTPUT);
  }
  for (int k = 0; k < 6; k++) {
    pinMode(showDig[k], OUTPUT);
  }

  //Los botones deben estar conectados a tierra [GND].
  pinMode(boton_1, INPUT_PULLUP);  // incrementa puntos player 1.
  pinMode(boton_2, INPUT_PULLUP);  // incrementa puntos player 2.
  pinMode(boton_start, INPUT_PULLUP); //inicia el juego

  escribirNumero(0);
  estado = ESTADO_STOP;
}

void loop() {

  switch (estado) {
    case ESTADO_STOP:

      for (int h = 0; h < 6; h++) {
        digitalWrite(showDig[h], 1);
        delay(retardo);
        digitalWrite(showDig[h], 0);
      }
      //
      leerPulsador_start();
      estado = ESTADO_START; 
      if (pulsador_start != estadoPulsadorAnterior_start) {
        if (antirebote(boton_start) == 0) {
          estado = ESTADO_START;
        }
      }
      estadoPulsadorAnterior_start = pulsador_start;
      break;

    case ESTADO_START:

      leerPulsador_1();
      leerPulsador_2();

      if (pulsador_1 != estadoPulsadorAnterior_1) {
        if (antirebote(boton_1) == 0) {         
          tiempoPulsador1Presionado = millis();          
        }
        else 
        {
        
          if (( millis() - tiempoPulsador1Presionado) > 1000 )
          {
            // borro contador de local o de visitante
            puntosLocal--;
            updateLocal();
            
          }
          else
          {
            puntosLocal++;
            updateLocal();
          
          }
        }
      }
      estadoPulsadorAnterior_1 = pulsador_1;

      if (pulsador_2 != estadoPulsadorAnterior_2) {
        if (antirebote(boton_2) == 0) {          
          // guardo en vaiable tiempoPulsadorPresionado = millis()
          tiempoPulsador2Presionado = millis();         
        }
        else 
        {
         
          if (( millis() - tiempoPulsador2Presionado) > 1000 )
          {
            // borro contador de local o de visitante
            puntosVisita--;
            updateVisita();
            
          }
          else
          {
            puntosVisita++;
            updateVisita();
           
          }
        }
      }
      estadoPulsadorAnterior_2 = pulsador_2;

      contarTiempo();
      updateDisplayTiempo();
      break;

    case ESTADO_FIN:
      updateDisplayTiempo();
      break;
  }
}

//FUNCIONES
void escribirNumero(int numero) {

  switch (numero) {
    case 0:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cero[j]);
      }
      break;
    case 1:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], uno[j]);
      }
      break;
    case 2:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], dos[j]);
      }
      break;
    case 3:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], tres[j]);
      }
      break;
    case 4:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cuatro[j]);
      }
      break;
    case 5:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cinco[j]);
      }
      break;
    case 6:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], seis[j]);
      }
      break;
    case 7:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], siete[j]);
      }
      break;
    case 8:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], ocho[j]);
      }
      break;
    case 9:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], nueve[j]);
      }
      break;
  }
}

void contarTiempo() {
  tiempoPasado = (millis() - tiempoInicio) / 1000;
  tiempoPasado /= 60;
  valor[0] = tiempoPasado / 10;
  valor[1] = tiempoPasado - (valor[0] * 10);
  if (valor[0] == 6) {
    estado =  ESTADO_FIN;
  }
}

void leerPulsador_1() {
  pulsador_1 = digitalRead(boton_1);
}

void leerPulsador_2() {
  pulsador_2 = digitalRead(boton_2);
}

void leerPulsador_start() {
  pulsador_start = digitalRead(boton_start);
}


void updateDisplayTiempo() {

  for (int h = 0; h < 6; h++) {
    escribirNumero(valor[h]);
    digitalWrite(showDig[h], 1);
    delay(retardo);
    digitalWrite(showDig[h], 0);
  }
}

void  updateVisita() {
  valor[2] = int(puntosVisita / 10);
  valor[3] = puntosVisita - (valor[2] * 10);
 
}

void  updateLocal() {
  valor[4] = int(puntosLocal / 10);
  valor[5] = puntosLocal - (valor[4] * 10);
 
}

boolean antirebote(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 < tiempoAntirebote);
  return estado;
}

uso arduino uno atmega328 con dos ULN2803

podrías poner un esquema para entender mejor software/hardware?

El tablero es para partidos de fútbol, acá les dejo como tengo configurados los pines del arduino, uso dos ULN2803, uno para los segmentos de los display y otro para los digitos.

 ================  ESQUEMA DE CONEXION  =================

                                      +-----+
         +----[PWR]-------------------| USB |--+
         |                            +-----+  |
         |         GND/RST2  [ ][ ]            |
         |       MOSI2/SCK2  [ ][ ]  A5/SCL[ ] |
         |          5V/MISO2 [ ][ ]  A4/SDA[ ] |
         |                             AREF[ ] |
         |                              GND[ ] |
         | [ ]N/C                    SCK/13[ ] |  Libre
         | [ ]IOREF                 MISO/12[ ] |  Libre
         | [ ]RST                   MOSI/11[ ]~|  Boton2
         | [ ]3V3    +---+               10[ ]~|  Boton1
         | [ ]5v    -| A |-               9[ ]~|  boton_start
         | [ ]GND   -| R |-               8[ ] |  Segmento g
         | [ ]GND   -| D |-                    |
         | [ ]Vin   -| U |-               7[ ] |  Segmento f
         |          -| I |-               6[ ]~|  Segmento e
  Dig1    | [ ]A0    -| N |-               5[ ]~|  Segmento d
  Dig2    | [ ]A1    -| O |-               4[ ] |  Segmento c
  Dig3    | [ ]A2     +---+           INT1/3[ ]~|  Segmento b
  Dig4    | [ ]A3                     INT0/2[ ] |  Segmento a
  Dig5    | [ ]A4/SDA  RST SCK MISO     TX>1[ ] |  Libre
  Dig6    | [ ]A5/SCL  [ ] [ ] [ ]      RX<0[ ] |  Libre
         |            [ ] [ ] [ ]              |
         |  UNO_R3    GND MOSI 5V  ____________/
          \_______________________/

****************************************************************/

Muchas gracias por sus aportes a todos, ya terminé el proyecto, me faltaba un delay en la rutina, quedó impecable el tablero, acá les dejo el code.

/***
   Proyecto: Pizarra Electronica
   created:  Agosto 2018
   Descripcion:
     - Control de tiempo y puntuacion para juegos.
     - Informacion de salida via 7 segmentos.
     - Tres estados [Espera]-[Juego]-[Fin] .

   Autores: Ing. Raúl Barrios Corrales
   Sitio web: www.formas.com.uy
   Mail: rbarrios@formas.com.uy


  ================  ESQUEMA DE CONEXION  =================

                                      +-----+
         +----[PWR]-------------------| USB |--+
         |                            +-----+  |
         |         GND/RST2  [ ][ ]            |
         |       MOSI2/SCK2  [ ][ ]  A5/SCL[ ] |
         |          5V/MISO2 [ ][ ]  A4/SDA[ ] |
         |                             AREF[ ] |
         |                              GND[ ] |
         | [ ]N/C                    SCK/13[ ] |  Libre
         | [ ]IOREF                 MISO/12[ ] |  Libre
         | [ ]RST                   MOSI/11[ ]~|  Boton2
         | [ ]3V3    +---+               10[ ]~|  Boton1
         | [ ]5v    -| A |-               9[ ]~|  boton_start
         | [ ]GND   -| R |-               8[ ] |  Segmento g
         | [ ]GND   -| D |-                    |
         | [ ]Vin   -| U |-               7[ ] |  Segmento f
         |          -| I |-               6[ ]~|  Segmento e
  Dig1    | [ ]A0    -| N |-               5[ ]~|  Segmento d
  Dig2    | [ ]A1    -| O |-               4[ ] |  Segmento c
  Dig3    | [ ]A2     +---+           INT1/3[ ]~|  Segmento b
  Dig4    | [ ]A3                     INT0/2[ ] |  Segmento a
  Dig5    | [ ]A4/SDA  RST SCK MISO     TX>1[ ] |  Libre
  Dig6    | [ ]A5/SCL  [ ] [ ] [ ]      RX<0[ ] |  Libre
         |            [ ] [ ] [ ]              |
         |  UNO_R3    GND MOSI 5V  ____________/
          \_______________________/

****************************************************************/

//DEFINICIONES.
#define boton_1 10
#define boton_2 9
#define boton_start 11

//DECLARACION DE VARIABLES.
int retardo = 1;     // tiempo que dura encendido cada 7 seg (1 mili segundos)
int t_digito_on = 1;
int t_digito_off = 1;
int estado;


const int ESTADO_STOP = 0;
const int ESTADO_START = 1;
const int ESTADO_FIN = 2;

unsigned long tiempoPasado = 0;
unsigned long tiempoInicio = 0;
unsigned long tiempoPulsador1Presionado;
unsigned long tiempoPulsador2Presionado;

boolean cero[] = {1, 1, 1, 1, 1, 1, 0};
boolean uno[] = {0, 1, 1, 0, 0, 0, 0};
boolean dos[] = {1, 1, 0, 1, 1, 0, 1};
boolean tres[] = {1, 1, 1, 1, 0, 0, 1};
boolean cuatro[] = {0, 1, 1, 0, 0, 1, 1};
boolean cinco[] = {1, 0, 1, 1, 0, 1, 1};
boolean seis[] = {1, 0, 1, 1, 1, 1, 1};
boolean siete[] = {1, 1, 1, 0, 0, 0, 0};
boolean ocho[] = {1, 1, 1, 1, 1, 1, 1};
boolean nueve[] = {1, 1, 1, 0, 0, 1, 1};

byte pinSeg[] = {2, 3, 4, 5, 6, 7, 8};//esta matriz contiene el valor de cada pin digital conectado a {a,b,c,d,e,f,g} del 7segmento
byte showDig[] = {A0, A1, A2, A3, A4, A5};//cada una de estas salidas en para activar cada digito [multiplexado].
int valor[6]; //En esta matriz almaceno el valor de cada digito del 7segmento

const int tiempoAntirebote = 10;



int pulsador_1;
int estadoPulsadorAnterior_1 = 1;
int pulsador_2;
int estadoPulsadorAnterior_2 = 1;
int pulsador_start;
int estadoPulsadorAnterior_start;

int puntosLocal = 0;
int puntosVisita = 0;


void setup() {
  Serial.begin(9600);
  for (int i = 0; i < 8; i++) {
    pinMode(pinSeg[i], OUTPUT);
  }
  for (int k = 0; k < 6; k++) {
    pinMode(showDig[k], OUTPUT);
  }

  //Los botones deben estar conectados a tierra [GND].
  pinMode(boton_1, INPUT_PULLUP);  // incrementa puntos player 1.
  pinMode(boton_2, INPUT_PULLUP);  // incrementa puntos player 2.
  pinMode(boton_start, INPUT_PULLUP); //inicia el juego

  escribirNumero(0);
  estado = ESTADO_STOP;
}

void loop() {

  switch (estado) {
    case ESTADO_STOP:

  updateDisplayTiempo();
      //
      leerPulsador_start();
      estado = ESTADO_START; /// sss_debug
      if (pulsador_start != estadoPulsadorAnterior_start) {
        if (antirebote(boton_start) == 0) {
          estado = ESTADO_START;
        }
      }
      estadoPulsadorAnterior_start = pulsador_start;
      break;

    case ESTADO_START:

      leerPulsador_1();
      leerPulsador_2();

      if (pulsador_1 != estadoPulsadorAnterior_1) {
        if (antirebote(boton_1) == 0) {
         
          // guardo en variable tiempoPulsadorPresionado = millis()
          tiempoPulsador1Presionado = millis();
          
        }
        else 
        {
          
          
          if (( millis() - tiempoPulsador1Presionado) > 1000 )
          {
            // borro contador de local o de visitante
            puntosLocal--;
            updateLocal();
           
          }
          else
          {
            puntosLocal++;
            updateLocal();
            
          }
        }
      }
      estadoPulsadorAnterior_1 = pulsador_1;

      if (pulsador_2 != estadoPulsadorAnterior_2) {
        if (antirebote(boton_2) == 0) {
          // guardo en vaiable tiempoPulsadorPresionado = millis()
          tiempoPulsador2Presionado = millis();
          
        }
        else 
        {
          
          if (( millis() - tiempoPulsador2Presionado) > 1000 )
          {
            // borro contador de local o de visitante
            puntosVisita--;
            updateVisita();
          
          }
          else
          {
            puntosVisita++;
            updateVisita();
            //Serial.println("Sume!!!!");
          }
        }
      }
      estadoPulsadorAnterior_2 = pulsador_2;

      contarTiempo();
      updateDisplayTiempo();
      break;

    case ESTADO_FIN:
      updateDisplayTiempo();
      break;
  }
}

//FUNCIONES
void escribirNumero(int numero) {

  switch (numero) {
    case 0:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cero[j]);
      }
      break;
    case 1:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], uno[j]);
      }
      break;
    case 2:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], dos[j]);
      }
      break;
    case 3:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], tres[j]);
      }
      break;
    case 4:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cuatro[j]);
      }
      break;
    case 5:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], cinco[j]);
      }
      break;
    case 6:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], seis[j]);
      }
      break;
    case 7:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], siete[j]);
      }
      break;
    case 8:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], ocho[j]);
      }
      break;
    case 9:
      for (int j = 0; j < 8; j++) {
        digitalWrite(pinSeg[j], nueve[j]);
      }
      break;
  }
}

void contarTiempo() {
  tiempoPasado = (millis() - tiempoInicio) / 1000;
  tiempoPasado /= 60;
  valor[0] = tiempoPasado / 10;
  valor[1] = tiempoPasado - (valor[0] * 10);
  if (valor[0] == 6) {
    estado =  ESTADO_FIN;
  }
}

void leerPulsador_1() {
  pulsador_1 = digitalRead(boton_1);
}

void leerPulsador_2() {
  pulsador_2 = digitalRead(boton_2);
}

void leerPulsador_start() {
  pulsador_start = digitalRead(boton_start);
}


void updateDisplayTiempo() {

  for (int h = 0; h < 6; h++) {
    escribirNumero(valor[h]);
    digitalWrite(showDig[h], 1);
    delay(t_digito_on);
    digitalWrite(showDig[h], 0);
    delay(t_digito_off);
  }
}

void  updateVisita() {
  valor[2] = int(puntosVisita / 10);
  valor[3] = puntosVisita - (valor[2] * 10);
  
}

void  updateLocal() {
  valor[4] = int(puntosLocal / 10);
  valor[5] = puntosLocal - (valor[4] * 10);
 
}

boolean antirebote(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 < tiempoAntirebote);
  return estado;
}