Common anode 7 segment display

Hi everyone.

I am new to Arduino and new to coding. I have tried to research the answer to my topic but I can't seem to find the right answer. I'm not a programmer of engineer. I'm a technician and a car main dealer and mainly do software updates to vehicles and electrical diagnostics. Anyway enough about me and here is my first code attempt and question.

I have written some code and successfully powered two 7 segment displays and counted to 20. The displays are common anode and the circuit works perfectly.

May question is the code is long and I wonder if there is a better way to write the code? As I'm learning any advice, suggestions or links to reading material would be highly appreciated. Here is my very basic code.

int segE1=0;
int segD1=1;
int segC1=2;
int segB1=3;
int segA1=4;
int segG1=5;
int segF1=6;

int segF2=7;
int segA2=8;
int segB2=9;
int segE2=10;
int segD2=11;
int segG2=12;
int segC2=13;
int wait=1000;

void setup() {

  pinMode(segA1,OUTPUT);
  pinMode(segB1,OUTPUT);
  pinMode(segC1,OUTPUT);
  pinMode(segD1,OUTPUT);
  pinMode(segE1,OUTPUT);
  pinMode(segF1,OUTPUT);
  pinMode(segG1,OUTPUT);
  
  pinMode(segA2,OUTPUT);
  pinMode(segB2,OUTPUT);
  pinMode(segC2,OUTPUT);
  pinMode(segD2,OUTPUT);
  pinMode(segE2,OUTPUT);
  pinMode(segF2,OUTPUT);
  pinMode(segG2,OUTPUT);
  
  }

void loop() {
  
  digitalWrite(segA1,LOW); // 00
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,LOW); //01
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,HIGH);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,LOW); //02
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,HIGH);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //03
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //04
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,HIGH);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //05
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,HIGH);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //06
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,HIGH);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //7
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,LOW); //08
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //09
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,LOW);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //10
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,HIGH); //11
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,HIGH);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,HIGH); //12
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,HIGH);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //13
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //14
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,HIGH);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //15
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,HIGH);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //16
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,HIGH);
  digitalWrite(segB2,HIGH);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //17
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,HIGH);
  digitalWrite(segG2,HIGH);
  delay(wait);

  digitalWrite(segA1,HIGH); //18
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,HIGH); //19
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,LOW);
  digitalWrite(segD1,HIGH);
  digitalWrite(segE1,HIGH);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,HIGH);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,HIGH);
  digitalWrite(segE2,HIGH);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,LOW);
  delay(wait);

  digitalWrite(segA1,LOW); //20
  digitalWrite(segB1,LOW);
  digitalWrite(segC1,HIGH);
  digitalWrite(segD1,LOW);
  digitalWrite(segE1,LOW);
  digitalWrite(segF1,HIGH);
  digitalWrite(segG1,LOW);
  digitalWrite(segA2,LOW);
  digitalWrite(segB2,LOW);
  digitalWrite(segC2,LOW);
  digitalWrite(segD2,LOW);
  digitalWrite(segE2,LOW);
  digitalWrite(segF2,LOW);
  digitalWrite(segG2,HIGH);
  delay(wait);

}

Look at the code for a seven segment library to see how it's done. I've never seen any that were not open source.

1 Like

You can refactor it into 1/10 of the original length if you use arrays and for loops. Also, use const when defining constants.

1 Like

All the above are explained in the reference section on this site.

1 Like

Thank you for the replies. I will do some more studying.

Here is an example of using arrays to greatly reduce the size of a Seven Segment sketch:

const byte Digit1Pins[7] = {4, 3, 2, 1, 0, 6, 5}; // A-G
const byte Digit2Pins[7] = {8, 9, 13, 11, 10, 7, 12};  // A-G

// Segment Cathodes (0/LOW for on, 1/HIGH for off)
const byte Segments[] =
{
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};

void setup()
{
  for (int i = 0; i < 7; i++)
  {
    pinMode(Digit1Pins[i], OUTPUT);
    pinMode(Digit2Pins[i], OUTPUT);
  }
}

void SetDigit(const byte * pinList, byte digitValue)
{
  byte segments = Segments[digitValue];

  for (int s = 0; s < 7; s++)
  {
    digitalWrite(pinList[s], segments & (0x40 >> s));
  }
}

void loop()
{
  for (int i = 0; i < 100; i++)
  {
    SetDigit(Digit1Pins, i / 10); // Tens digit
    SetDigit(Digit2Pins, i % 10); // Units digit
    delay(1000);
  }
}
1 Like

You should also consider multiplexing the display, it will save you a lot of pins.

1 Like

Wow thank you. That is very helpful. Thanks for taking the time to share this.

Yes my next project is to use the 74HC595 to save pins.

1 Like

Don't forget the current limiting resistors.

Here is one solution using SevSeg.h Library.
1. Build the following 2-digit CA7SD Unit (Fig-1).

ca7seg2dig
Figure-1:

2. Upload the following sketch.


#include<SevSeg.h>
SevSeg sevSeg;           //create object sevSeg

byte numberToShow = 45;

void setup()
{
  byte segDPins[] = {2, 3, 4, 5, 6, 7, 8, 9};//DPin-2 = seg-a, …, DPin-9 = seg-p
  byte caDPins[] = {A0, A1};   //DPin-A0 = cca0, DPin-A1 = ca1
  sevSeg.begin(COMMON_ANODE, 2, caDPins, segDPins, false, false, false, true);
  sevSeg.setNumber(numberToShow, 0, LOW); //arg1 = 00 - 99; arg2 = no decimal point; arg3=base-10
}

void loop()
{
  sevSeg.refreshDisplay();  //keep refreshing display
}

3. Check that 45 has appeared on the display unit.
4. The Tutorial of this link may worth practicing with regards to SevSeg.h.

1 Like

If you want to put in an extra IC, the MAX7219 will do the job. It's a common cathode driver, really, but here you can find a clever workaround.

1 Like

Then, who will write the codes for MAX7219-based display unit (Fig-1) when @mark2383 is an auto mechanic.

max7219-2D
Figure-1:

1 Like

Probably, GolamMostafa. :slight_smile:

2 Likes

Really appreciate the replies. It's giving me loads to look into. I'm just learning this for fun. Hopefully I will get better day by day.

1 Like

This is the tutorial to show 25 on the cc-type multiplexed display unit of Fig-1 being driven by MAX7219 Display Controller. The theory of operation/programming of MXA7219 chip will be found at the end of this tutorial starting from Step-3.

max7219-2D
Figure-1:

1. Make connection among UNO, MAX7219, and Display Unit as per Fig-1. Please, palce C1 very close to Pin-19 of MAX7219 to kill the switching noise.

2. Upload the following sketch and check that 25 has appeared on the display unit.

#include<SPI.h>
#define LOAD 10

byte registerAddress[] = {0x09, 0x0A, 0x0B, 0x0C};//Decode Mode,Intensity,Scan Limit,Shutdown
byte registerData[] = {0x00, 0xFF, 0x07, 0x01};   //data for above registers respectively
byte digitAddress[] = {0x01, 0x02};//address for digitas of positions DP0-DP1
byte lupTable[] = //No-decode B-Font cc-code (p a b c d e f g) for charcaters: 0 - 9, A - F
{   
  0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70,
  0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47
}; 
//--------------------------------------------------------------

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  digitalWrite(LOAD, LOW);   //auotomatically OUTPUT due to SPI.begin()
  //----MAX7219 initialization----------------
  for (int i = 0; i < 4; i++)
  {
    SPI.transfer(registerAddress[i]);//address of Control Registers
    SPI.transfer(registerData[i]); //data for Control Registers
    dataLoad();     //generates L-H-L pulse at the LOAD pin of MAX7219
  }
  SPI.transfer(digitAddress[0]);   //address of DP0-digit
  SPI.transfer(lupTable[2]);      //B-Font code for digit-2
  dataLoad();
  //---------------------------------------------------
  SPI.transfer(digitAddress[1]);   //address of DP1-digit
  SPI.transfer(lupTable[5]);      //B-Font code for digit-5
  dataLoad();
}

void loop()
{

}

void dataLoad()
{
  digitalWrite(LOAD, HIGH);
  delayMicroseconds(1);
  digitalWrite(LOAD, LOW);
}

3. Working Principle
CC-type 7-segment display devices can be directly connected with MAX7219 controller; where, the segment currents are controlled by Rex1 (Fig-1) resistor and the content of Intensity Register.

A single MAX7219 can handle as many as 8 digits in multiplexed mode. Multiple MAX7219 chips can be cascaded using DOUT-pin to handle bigger display unit (Fig-4).

For each digit there is an 8-bit wide RAM location (with unique address) inside the controller. The MCU can write new data at any time into this RAM location, and the data is immediately transferred into the target digit and refreshed with the help of built-in scanning circuit.

Before the controller is put into operation, it needs to be configured/initialized by storing appropriate data (see sketch) into the following registers: No-decode Mode, Intensity, Scan Limit, and Shutdown Registers.

The controller accepts 16-bit "command word (Fig-2)" from the host MCU. The upper 8-bit of the command word is the "address" of the target register and the lower 8-bit is the "data" for that register.

The 16-clocking pulses (required to push-out command word) can be genrated by the SCK-pin of the SPI Port in two transaction cycles. The data enters into a temporary buffer (Fig-2) and then into the respective registers when L-H-L pulse is asseted on the LOAD-pin of the controller. For example: to store 0x01 into the Shutdown Register, we may execute the following codes:

SPI.transger(0x0C); //0x0C is the address of Shutdown Register
SPI.transfer(0x01);  //0x01 is the data for Shutdown Register.
digitalWrite(10, HIGH);  //asserting L-H-L pulse at the LOAD-pin of MAX7219
delayMicroseconds(1);
digitalWrite(10, LOW);

max7219CommandFormat
Figure-2:

4. No-decode B-Font CC-codes for charcaters 0 - 9, A - F
The active bits for the segments of the cc-type 7-segment device are arranged as per Fig-3 and the 8-bit codes are formed accordingly (known as no-decode B-Font). For example: the B-fornt for charcater 2 is: 0x6D (0110 1101 = DP A B C D E F G)


Figure-3:

5. Cascade Operaion of two MAX7219 Controllers

max7219-16dig
Figure-4:

(1) Codes to initialize both controllers.

byte registerAddress[] = {0x09, 0x0A, 0x0B, 0x0C};//Decode Mode,Intensity,Scan Limit,Shutdown
byte registerData[] = {0x00, 0xFF, 0x07, 0x01};   //data for above registers respectively
for (int i = 0; i <= 3; i++)
{
    SPI.transfer(registerAddress[i]);//address of Control Registers
    SPI.transfer(registerData[i]); //data for Control Registers
    dataLoad();

    SPI.transfer(registerAddress[i]);//(0x09); //decode mode
    SPI.transfer(registerData[i]);//(0x00); //no-decode mode
    SPI.transfer(0x00); //address of No-Op Register
    SPI.transfer(0xFF); //data (any value) for No-Op Register
    dataLoad();
}

(2) Role of No-Op (No Operation) Register in Cascading


Figure-5:

Initialization of the second MAX7219 is done with the help of No-Op (No Operation) Register. Command word 0x0900 (0900 = 0x00 data for Decode Mode Register with address 0x09) is transferred into temporary buffer of U1 (Fig-5). After that load pulse (L-H-L) is asserted and the data is latched in the Decode Mode Register of U1.

The same command word (0900) is again loaded into temporary buffer of the first MAX7219 chip (U1, Fig-5). Now, it has to be transferred into the temporary buffer of the second MAX7219 chip (U2, Fig-5) using DOUT-pin of U1; where, DOUT-pin of U1 is connected with DIN-line of U2. To do it, we need to generate 16 CLK pulses which are generated by sending command word 0x00FF (00FF = 0xFF data byte for No-Op Register with address 0x00) into the temporary buffer of first MAX7219 (U1). Now, load pulse is asserted; as a result, 0xFF enters into No-Op Register of U1 without affecting the contents of other registers, and 0x00 enters into the Decode Mode Register of U2.

1 Like

Thanks for the replies. Its really helping me learn. I have now advanced to using 2 74HC595 to drive 2 digits on 7 segment displays. I have started using arrays as advised in this thread. Both digits are now counting from 0 to F. I want to next learn how to have each digit count independently. Can you suggest how this can be done? Or point me to some information i can read to learn myself. Here is my code so far:



#define dataPin 2
#define latchPin 3
#define clockPin 4
#define DT 500

byte digits []{
 0x81, //0b10000001; 0 
 0xF3, //0b11110011; 1
 0x49, //0b01001001; 2
 0x61, //0b01100001; 3
 0x33, //0b00110011; 4
 0x25, //0b00100101; 5
 0x05, //0b00000101; 6
 0xF1, //0b11110001; 7
 0x01, //0b00000001; 8
 0x21, //0b00100001; 9 
 0x11, //0b00010001; A
 0x07, //0b00000111; B
 0x8D, //0b10001101; C
 0x43, //0b01000011; D
 0x0D, //0b00001101; E
 0x1D, //0b00011101; F
};

void setup() {
 pinMode(latchPin,OUTPUT);
 pinMode(dataPin,OUTPUT);
 pinMode(clockPin,OUTPUT);
}

void loop() {

 for (int i=0;i<=15;i=i+1){
digitalWrite(latchPin,HIGH);
shiftOut(dataPin,clockPin,MSBFIRST,digits[i]);
shiftOut(dataPin,clockPin,MSBFIRST,digits[i]);
digitalWrite(latchPin,LOW);
delay(DT);
 }

}

Why not just

byte digits []{
 0b10000001; // 0
...

??

Strange question. You can already do that, you just chose not to, by shifting out digits[i] and using i twice. If you used some value other than 'i', that's what would be displayed... example:

shiftOut(dataPin,clockPin,MSBFIRST,digits[i]);
shiftOut(dataPin,clockPin,MSBFIRST,digits[k]);

If your question is, "how do I choose a different value of 'k'?", then you need to just study C. There are so many tutorial sites online, all you need to do is Google them.

For demonstration purposes you could do something like

k = (i + 5) % 10;

I could but I was playing with both hex and binary.