Inizierei con il dare nomi espliciti ai pin tramite apposite costanti, perché pur guardando ho capito solo che il 3 è il punto (in questo senso il codice non è autodocumentante, immagina di rileggerlo tra un anno senza il circuito sotto mano).
Diamo per scontato che i segmenti hanno questa disposizione?
// A
// ---
// F | | B
// -G-
// E | | C
// --- .DP
// D
Compiliamo allora una serie di costanti iniziali per usare i nomi dei segmenti nel programma al posto dei numeri dei pin:
const uint8_t A_PIN =
const uint8_t B_PIN =
const uint8_t C_PIN =
const uint8_t D_PIN =
const uint8_t E_PIN =
const uint8_t F_PIN =
const uint8_t G_PIN =
const uint8_t DP_PIN = 3;
Poi possiamo creare un array di pin utile per scorrere i segmenti con un indice da 0 a 7.
Nota: in questo modo non c'è neppure più bisogno che i pin a cui sono collegati i segmenti siano in sequenza numerica:
const uint8_t SEG_PIN_ARRAY[] = {
A_PIN, B_PIN, C_PIN, D_PIN,
E_PIN, F_PIN, G_PIN, DP_PIN
};
A questo punto le seguenti istruzioni sono equivalenti:
digitalWrite(3, HIGH);
digitalWrite(DP_PIN, HIGH);
digitalWrite(SEG_PIN_ARRAY[7], HIGH);
La prima non la usiamo più, perché lo scopo è non vedere più numeri di pin in giro per il programma (si parametrizza tutto con nomi costanti all'inizio).
La seconda è utile per agire sul singolo segmento.
La terza per scorrere i segmenti in automatico con un ciclo, ad esempio per spegnere tutto:
for (uint8_t i=0; i<=7; i++)
digitalWrite(SEG_PIN_ARRAY[i], LOW);
Non serve ogni volta specificare il pinMode. Se non ci sono motivi tecnici per volerlo fare, basta una sola volta nel setup e i pin mantengono la "direzione" per tutto il tempo.
Nota: uint8_t indica semplicemente un byte, un intero a 8 bit senza segno (U)nsigned.