Futbolín con doble marcador

Se trata de construir un futbolín en el que la entrada de una bola por la portería es detectada por una barrera de infrarrojos que se utiliza para modificar el valor de dos variables que indican los tantos conseguidos por cada jugador. Estas dos variables, posteriormente se muestran en dos displays de cuatro dígitos y 7 segmentos, conectados mediante un bus I2C.

El display de 7 segmentos

Un display de 7 segmentos está formado por 7 LEDs para los segmentos que forman los diferentes números y uno más que hará de punto.

Algunos de estos componentes incorporan una conexión para bus i2C que facilita la conexión a Arduino.

El bus i2C

El estándar I2C (Inter-Integrated Circuit) fue desarrollado por Philips en 1982 para la comunicación interna de dispositivos electrónicos en sus artículos. Posteriormente fue adoptado progresivamente por otros fabricantes hasta convertirse en un estándar del mercado.

El bus I2C requiere únicamente dos cables para su funcionamiento, uno para la señal de reloj (CLK) y otro para el envío de datos (SDA).

En el bus cada dispositivo dispone de una dirección, que se emplea para acceder a los dispositivo de forma individual. Esta dirección puede ser fijada por hardware (en cuyo caso, frecuentemente, se pueden modificar los últimos 3 bits mediante jumpers o interruptores) o totalmente por software.

Display de 4 dígitos y 7 segmentos de Gravitech

La compañía Gravitech fabrica y distribuye un display de 4 dígitos y 7 segmentos, con un controlador SAA1064 en tecnología CMOS, conectado mediante 5 pines a un bus I2C.

El display no necesita componentes externos. De los 5 pines de conexión, solamente se utilizan 4, dos para las señales SDA (pin A4 de Arduino UNO) y SCL (pin A5 de Arduino UNO) y los otros dos para la tensión de alimentación y la tierra.

Mediante la librería #include <Wire.h> Arduino puede poner en marcha estos displays a través del bus I2C.

El puerto por defecto en el display es el 56 (decimal) 0x38 (hexadecimal), pero modificando el puente hecho con soldadura pasa a ser el 59 (decimal) 0x3B (hexadecimal). De esta forma se pueden utilizar dos displays simultáneamente.

Primer programa para poner en marcha el Display

A continuación se muestra este programa que muestra un marcador de 5 a 8, a favor del jugador de la derecha.

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

Display de 4 dígitos y 7 segmentos, conectado por I2C de Gravitech

display derecho dirección 56 (decimal) 0x38 (hexadecimal)

display izquierdo dirección 59 (decimal) 0x3B (hexadecimal)

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

#include <Wire.h>

void setup()

{

Wire.begin(); // Configuración del bus I2C

delay(500);

Wire.beginTransmission(56);

Wire.write(0);

Wire.write(B01000111);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(0);

Wire.write(B01000111);

Wire.endTransmission();

}

void loop()

{

Wire.beginTransmission(56); //Display de la derecha

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01111111);

Wire.endTransmission();

Wire.beginTransmission(56);

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000000);

Wire.endTransmission();

Wire.beginTransmission(56);

Wire.write(3); //Tercer dígito por la derecha

Wire.write(B01110111);

Wire.endTransmission();

Wire.beginTransmission(56);

Wire.write(4); //Cuarto dígito por la derecha

Wire.write(B11110101);

Wire.endTransmission();

Wire.beginTransmission(59); //Display de la izquierda

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01101101);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000000);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(3); //Tercer dígito por la derecha

Wire.write(B01111001);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(4); //Cuarto dígito por la derecha

Wire.write(B00111000);

Wire.endTransmission();

}

Marcador con dos displays y dos sensores digitales

#include <Wire.h>

int marcador1 = 0;

int marcador2 = 0;

int unidades = 0;

int decenas = 0;

void setup()

{

Wire.begin(); // Configuración del bus I2C

delay(500);

Wire.beginTransmission(56);

Wire.write(0);

Wire.write(B01000111);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(0);

Wire.write(B01000111);

Wire.endTransmission();

Serial.begin(9600);

}

void loop()

{

Serial.println(marcador1);

Serial.println(marcador2);

if(digitalRead(6)==LOW){

marcador1 = marcador1 + 1;

delay(1000);

}

if(digitalRead(7)==LOW){

marcador2 = marcador2 + 1;

delay(1000);

}

decenas = (int)(marcador1/10);

unidades = marcador1 - decenas * 10;

Wire.beginTransmission(56); //Display de la derecha

if(unidades==0){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00111111);//0

Wire.endTransmission();

}

if(unidades==1){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00000110);//1

Wire.endTransmission();

}

if(unidades==2){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01011011);//2

Wire.endTransmission();

}

if(unidades==3){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01001111);//3

Wire.endTransmission();

}

if(unidades==4){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01100110);//4

Wire.endTransmission();

}

if(unidades==5){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01101101);//5

Wire.endTransmission();

}

if(unidades==6){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01111101);//6

Wire.endTransmission();

}

if(unidades==7){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00000111);//7

Wire.endTransmission();

}

if(unidades==8){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01111111);//8

Wire.endTransmission();

}

if(unidades==9){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01100111);//9

Wire.endTransmission();

}

Wire.beginTransmission(56);

if(decenas==0){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00111111);//0

Wire.endTransmission();

}

if(decenas==1){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000110);//1

Wire.endTransmission();

}

if(decenas==2){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01011011);//2

Wire.endTransmission();

}

if(decenas==3){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01001111);//3

Wire.endTransmission();

}

if(decenas==4){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01100110);//4

Wire.endTransmission();

}

if(decenas==5){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01101101);//5

Wire.endTransmission();

}

if(decenas==6){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01111101);//6

Wire.endTransmission();

}

if(decenas==7){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000111);//7

Wire.endTransmission();

}

if(decenas==8){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01111111);//8

Wire.endTransmission();

}

if(decenas==9){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01100111);//9

Wire.endTransmission();

}

Wire.beginTransmission(56);

Wire.write(3); //Tercer dígito por la derecha

Wire.write(B01110111);

Wire.endTransmission();

Wire.beginTransmission(56);

Wire.write(4); //Cuarto dígito por la derecha

Wire.write(B11110101);

Wire.endTransmission();

decenas = (int)(marcador2/10);

unidades = marcador2 - decenas * 10;

Wire.beginTransmission(59); //Display de la derecha

if(unidades==0){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00111111);//0

Wire.endTransmission();

}

if(unidades==1){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00000110);//1

Wire.endTransmission();

}

if(unidades==2){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01011011);//2

Wire.endTransmission();

}

if(unidades==3){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01001111);//3

Wire.endTransmission();

}

if(unidades==4){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01100110);//4

Wire.endTransmission();

}

if(unidades==5){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01101101);//5

Wire.endTransmission();

}

if(unidades==6){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01111101);//6

Wire.endTransmission();

}

if(unidades==7){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B00000111);//7

Wire.endTransmission();

}

if(unidades==8){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01111111);//8

Wire.endTransmission();

}

if(unidades==9){

Wire.write(1); //Primer dígito por la derecha

Wire.write(B01100111);//9

Wire.endTransmission();

}

Wire.beginTransmission(59);

if(decenas==0){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00111111);//0

Wire.endTransmission();

}

if(decenas==1){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000110);//1

Wire.endTransmission();

}

if(decenas==2){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01011011);//2

Wire.endTransmission();

}

if(decenas==3){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01001111);//3

Wire.endTransmission();

}

if(decenas==4){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01100110);//4

Wire.endTransmission();

}

if(decenas==5){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01101101);//5

Wire.endTransmission();

}

if(decenas==6){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01111101);//6

Wire.endTransmission();

}

if(decenas==7){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B00000111);//7

Wire.endTransmission();

}

if(decenas==8){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01111111);//8

Wire.endTransmission();

}

if(decenas==9){

Wire.write(2); //Segundo dígito por la derecha

Wire.write(B01100111);//9

Wire.endTransmission();

}

Wire.beginTransmission(59);

Wire.write(3); //Tercer dígito por la derecha

Wire.write(B01111001);

Wire.endTransmission();

Wire.beginTransmission(59);

Wire.write(4); //Cuarto dígito por la derecha

Wire.write(B00111000);

Wire.endTransmission();

}

Programa que escanea para encontrar las direcciones conectadas

El siguiente programa escanea el bus I2C, para encontrar las direcciones de los dispositivos conectados.

#include "Wire.h"

extern "C" {

#include "utility/twi.h"

}

void scanI2CBus(byte from_addr, byte to_addr, void(*callback)(byte address, byte result) )

{

byte rc;

byte data = 0;

for( byte addr = from_addr; addr <= to_addr; addr++ ) {

rc = twi_writeTo(addr, &data, 0, 1, 0);

callback( addr, rc );

}

}

void scanFunc( byte addr, byte result ) {

Serial.print("addr: ");

Serial.print(addr,DEC);

Serial.print( (result==0) ? " Encontrado!":" ");

Serial.print( (addr%4) ? "\t":"\n");

}

const byte start_address = 8;

const byte end_address = 119;

void setup()

{

Wire.begin();

Serial.begin(9600);

Serial.print("Escaneando bus I2C...");

scanI2CBus( start_address, end_address, scanFunc );

Serial.println("\nTerminado");

}

void loop()

{

delay(1000);

}