Recientemente he tenido que aprender a usar pantallitas de 4 dígitos con 7 segmentos en Arduino. Es decir, algo como ésto:

4 digit, 7 segment display
4 digit, 7 segment display

Como pasa con todo la primera vez siempre cuesta. Y más si hay distintos tipos de displays y por tanto varias formas de hacer las cosas según el modelo que te haya caído a ti (los chinos no son muy dados a mandar manuales de uso para estas cosas). Y no son sutilezas, más bien hay dos formas, totalmente opuestas, así que os voy a dejar un par de ejemplos.
Antes de verlos decir que en cualquier caso es necesario entender que la pantalla hay que pintarla una y otra vez. Es decir, no basta con pintar y dejarlo encendido, porque eso es imposible. Básicamente porque en realidad «pintar la pantalla» no es una tarea, son cuatro: pintar el primer dígito, luego el segundo, luego el tercero y finalmente el cuarto.
Y cuando digo «luego» quiero decir unos milisegundos más tarde. No se pueden hacer las cuatro tareas a la vez, sólo se puede pintar de dígito en dígito. Seguramente esto se entienda viendo un esquema de pines:

Esquema de pines

Como podéis ver hay 4 pines, uno para cada dígito. Esos son los pines que usaremos para seleccionar el dígito que queramos pintar. ¿Se entiende ahora lo de que son 4 tareas que no se pueden hacer a la vez?
Pues visto esto, vamos a los casos concretos:

Primer ejemplo:

Para el display de la primera imagen, que es de tipo cátodo común y tiene 12 pines (por cierto, ojo que un trasto de estos te deja casi sin pines en arduino!), comprado en Dealextreme por 2$:

//pseudocódigo
En loop():
(1) Poner los 4 cátodos a HIGH (los selectores de dígito)
(2) Los segmentos deseados a HIGH
(3) El cátodo del primer dígito a LOW
(4) Delay (sleep)

Repetir para el dígito 2

Repetir para el dígito 3

Repetir para el dígito 4

Ahora que más o menos tenemos la idea, vamos a ver código de verdad:

//Declare what pins are connected to the digits
int digit1 = 12; //Pin 12 on my 4 digit display
int digit2 = 9; //Pin 9 on my 4 digit display
int digit3 = 8; //Pin 8 on my 4 digit display
int digit4 = 2; //Pin 6 on my 4 digit display

//Declare what pins are connected to the segments
int segA = 11; //Pin 11 on my 4 digit display
int segB = 7; //Pin 7 on my 4 digit display
int segC = 4; //Pin 4 on my 4 digit display
int segD = 5; //Pin 2 on my 4 digit display
int segE = 6; //Pin 1 on my 4 digit display
int segF = 10; //Pin 10 on my 4 digit display
/*int segH = 13; //Pin 3 on my 4 digit display*/
int segG = 3; //Pin 5 on my 4 digit display

void setup() {
  for(int i=2; i<=13; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {
  printStop();
  delay(15);
}

// clear selection
void digitsHigh() {
  digitalWrite(digit1, HIGH);
  digitalWrite(digit2, HIGH);
  digitalWrite(digit3, HIGH);
  digitalWrite(digit4, HIGH);
}

//clear segments
void clearDigit() {
  digitalWrite(segA, LOW);
  digitalWrite(segB, LOW);
  digitalWrite(segC, LOW);
  digitalWrite(segD, LOW);
  digitalWrite(segE, LOW);
  digitalWrite(segF, LOW);
  digitalWrite(segG, LOW);
  //digitalWrite(segH, LOW);
}

//print "STOP"
void printStop() {
  //S
  digitsHigh();
  digitalWrite(segA, HIGH);
  digitalWrite(segF, HIGH);
  digitalWrite(segG, HIGH);
  digitalWrite(segC, HIGH);
  digitalWrite(segD, HIGH);
  digitalWrite(digit1, LOW);
  delayMicroseconds(500);
  clearDigit();

  //t
  digitsHigh();
  digitalWrite(segF, HIGH);
  digitalWrite(segG, HIGH);
  digitalWrite(segE, HIGH);
  digitalWrite(segD, HIGH);
  digitalWrite(digit2, LOW);
  delayMicroseconds(500);
  clearDigit();

  //O
  digitsHigh();
  digitalWrite(segA, HIGH);
  digitalWrite(segB, HIGH);
  digitalWrite(segC, HIGH);
  digitalWrite(segD, HIGH);
  digitalWrite(segE, HIGH);
  digitalWrite(segF, HIGH);
  digitalWrite(digit3, LOW);
  delayMicroseconds(500);
  clearDigit();

  //P
  digitsHigh();
  digitalWrite(segA, HIGH);
  digitalWrite(segB, HIGH);
  digitalWrite(segG, HIGH);
  digitalWrite(segF, HIGH);
  digitalWrite(segE, HIGH);
  digitalWrite(digit4, LOW);
  delayMicroseconds(500);
  clearDigit();
}

Segundo ejemplo:

Este otro display es casi igual, solo que tiene dos puntos en medio y por tanto un pin más, pero lo importante es que el funcionamiento es opuesto al que acabamos de ver:

//pseudocódigo
(1) Poner los 4 dígitos a LOW (es decir, los 4 pines selectores)
(2) Poner todos los segmentos a HIGH
(3) Los segmentos deseados a LOW
(4) El primer dígito a HIGH
(5) Delay (sleep)

Repetir para el dígito 2

Repetir para el dígito 3

Repetir para el dígito 4

¿Diferente verdad? Veamos código de verdad:

//Declare what pins are connected to the digits
int digit1 = 12; //Pin 12 on my 4 digit display
int digit2 = 9; //Pin 9 on my 4 digit display
int digit3 = 8; //Pin 8 on my 4 digit display
int digit4 = 2; //Pin 6 on my 4 digit display

//Declare what pins are connected to the segments
int segA = 11; //Pin 11 on my 4 digit display
int segB = 7; //Pin 7 on my 4 digit display
int segC = 4; //Pin 4 on my 4 digit display
int segD = 5; //Pin 2 on my 4 digit display
int segE = 6; //Pin 1 on my 4 digit display
int segF = 10; //Pin 10 on my 4 digit display
/*int segH = 13; //Pin 3 on my 4 digit display*/
int segG = 3; //Pin 5 on my 4 digit display

void setup() {
  for(int i=2; i<=13; i++) {
    pinMode(i, OUTPUT);
  }
}

void loop() {
  printStop();
  delay(15);
}

// write 'level' to all segments
void allSegments(int level) {
  digitalWrite(segA, level);
  digitalWrite(segB, level);
  digitalWrite(segC, level);
  digitalWrite(segD, level);
  digitalWrite(segE, level);
  digitalWrite(segF, level);
  digitalWrite(segG, level);
}

//write 'level' to all digit selectors
void allDigits(int level) {
  digitalWrite(digit1, level);
  digitalWrite(digit2, level);
  digitalWrite(digit3, level);
  digitalWrite(digit4, level);
}

//print "STOP"
void printStop() {
  //S
  allDigits(LOW);//clear digits
  allSegments(HIGH);//clear segments
  digitalWrite(segA, LOW);
  digitalWrite(segF, LOW);
  digitalWrite(segG, LOW);
  digitalWrite(segC, LOW);
  digitalWrite(segD, LOW);
  digitalWrite(digit1, HIGH);
  delayMicroseconds(500);

  //t
  allDigits(LOW);
  allSegments(HIGH);
  digitalWrite(segF, LOW);
  digitalWrite(segG, LOW);
  digitalWrite(segE, LOW);
  digitalWrite(segD, LOW);
  digitalWrite(digit2, HIGH);
  delayMicroseconds(500);

  //O
  allDigits(LOW);
  allSegments(HIGH);
  digitalWrite(segA, LOW);
  digitalWrite(segB, LOW);
  digitalWrite(segC, LOW);
  digitalWrite(segD, LOW);
  digitalWrite(segE, LOW);
  digitalWrite(segF, LOW);
  digitalWrite(digit3, HIGH);
  delayMicroseconds(500);

  //P
  allDigits(LOW);
  allSegments(HIGH);
  digitalWrite(segA, LOW);
  digitalWrite(segB, LOW);
  digitalWrite(segG, LOW);
  digitalWrite(segF, LOW);
  digitalWrite(segE, LOW);
  digitalWrite(digit4, HIGH);
  delayMicroseconds(500);
}

Eso es todo, espero que os sirva, a mi me llevó varias horas dar con la fórmula para cada uno de los displays 😛

If you think my content is worth it you can Buy me a Coffee at ko-fi.com Buy me a Ko-fi