About Me

My photo
They never fall who never climb.

023 SEVEN-SEGMENT LED DISPLAY - DOUBLE DIGIT


023 SEVEN-SEGMENT LED DISPLAY - DOUBLE DIGIT

April 1, 2011    (See also Companion Blog )
[Go BACK to Table of Contents] [ Next Experiment ] [ Last Experiment ]
Goal:
           To test the operation of a two-digit display of seven-segment LED lamps. The focus of the test is to keep the number of leads to the lamps as few as possible, as there are not enough output pins on the Arduino controller to simply double the number.

Theory:
           The pins of the diodes are connected in series, that is, all the “a” segments are in a single string, same with all the “b”, “c” and so on. Thus, only seven leads are necessary from the Arduino, and again, I chose pins 3 through 9 to avoid any special purpose pins.

           There are also two transistors to control the common cathode (ground). These transistors are to rapidly flash the ground connections on and off so that only one ground is active at any given instant. Thus, only that LED lamp will display the desired digit. If not for the ground connection, all the LED lamps would display the same digit, since they would all be on at the same instant.

           A display of digits is therefore, like the single digit, largely an illusion caused by POV (persistence of vision). If I was learning this new, I would make sure the following schematic makes sense before continuing. I’ll try to help by explaining the parts that are difficult to draw or visualize.

           The Arduino pins are easy to follow. However, look at the representations of the seven-segment LED lamps. The alphabetic segment names are not arranged, well, alphabetically. What I’ve tried to show here is how lamp pin 14, the “a” segment, is connected on both lamps and runs over to pin Arduino pin 3. This is a single leg of the circuit. Now look at lamp pin 1, the “f” segment. It is also connected in series, but runs over to Arduino pin 9.

           I’ve tried to emphasize this by using a different style of line for the lamp pins on the right side of each symbol. I found it helps to imagine the Arduino current running into lamp pin 1 from the left and into lamp pin 14 from the right.

           What is really happening is both lamps are showing the same number, but only one of them is “ON” at any given moment thanks to the transistor. Anyway, that is my theory, and I came up with this on my own, not via study or examples. This effect seems to work, so it is explained again in the next section. Better to over-explain these things, if you ask me.

Practice:
           Initial success. Shown here are two numbers, 75 and 36, displayed horizontally in each case. This arrangement is due to the design of the breadboard and the pin arrangement back of the lamps. The reality is that in the first instance, both lamps show a 7 for a split second, then both show a 5 the next split second.

           There is a transistor (switch) which turns off one of the lamps and turns the other on. This flops back and forth so fast, it appears the two digits are displaying independently.
           This proves at least my theory of one way to accomplish the goal of multiple digit numbers. However, this is far from a practical experiment. Allow me to give reasons why not.

           First, the numbers are arbitrary, they are not measuring anything. I have to change the computer code and upload each pair of numbers. The wiring, even if I did not use jumpers, is impractical in this fashion. Also, if you squint, you can see the LEDs that are supposed to be OFF show a faint back-glow that makes the display a little harder to read. I wonder if that is why many devices using these lamps are placed behind a smoked glass panel?

           The numbers are only half as bright as displayed when the same Arduino power was used on a single lamp. This may be the reason other circuits show a transistor. It is not a switch, but a way to light the LED using external power so the brightness can be maximized, and I should have been able to figure that out. So, my original experiments with these circuits were right, but I attached the wrong meaning to half the transistors.

Conclusion:
           This experiment drew on every LED experiment I’ve done in the past, it was a real challenge. There are at least two possibilities. One is that I’ve correctly derived the electronics behind bigger and better LED signs. The other is that I’ve found a blind alley that works but is impractical on a larger scale.

           It will be wise to study more about transistors, particularly how they are used as rapid switches. I wasted at least eight hours trying to get the faint glow of an “off” LED to go away, only to discover that increasing the value of the resistor to the point where it was gone also dimmed the brightness of the diode when it was glowing.

           Of note also is that this single circuit combines for the first time many of the elements I’ve tested. This is a multiplexed circuit, though I did not really design the multiplexer. It uses transistor switching, which I have not yet mastered. The code is a brute force approach because I have never employed a two-dimensional array because I have only studied them, never built one.

           The military calls this kind of experiment a “demonstration of technological superiority”. I can make it work. What remains is to figure out why it works and see if it has any practical application.

           I later tweaked the code to count down from 30 to 1 in approximately one second intervals. I intentionally avoided arrays and embedded loops to keep the code readable to non-programmers, as shown below. One trade-off was I had to flash the numbers separately and each display is a separate call to a subroutine. There are no counters used in this code. Take a look at how I did it. This is the “programming for dummies” approach and it was so much extra work, I may never repeat it.

Here is the code:

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

/* This is an LED dot matrix experiment
 * It matches Experiment 022 in the Minutes
 * This experiment is to light the Arabic digits 0-20
 * on a two 7-segment LED lamps without using an
 * integrated.
 * Today is April 19, 2011
 */
 
////////////////////////////////////////////////////////////////////////////
//Begin Initialization & Variables

int SegmentA = 9; //Assign pins to the corresponding LED Segments
int SegmentB = 8; //There are 7 segments, called A thru G
int SegmentC = 7; //on the LED design.
int SegmentD = 6; //
int SegmentE = 5; //
int SegmentF = 4; //
int SegmentG = 3; //

int Lamp01Pin = 11; //Controls first LED lamp
int Lamp02Pin = 12; //Controls second LED lamp

int vDelay = 500; //To adjust the ON/OFF interval

//End Initialization & Variables
////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
// Begin Main Program
////////////////////////////////////////////////////////////////////////////

void setup()
{
  pinMode(SegmentA, OUTPUT); //all pins used in this sketch are outputs
  pinMode(SegmentB, OUTPUT); //do not neglect these commands, as all pins on
  pinMode(SegmentC, OUTPUT); //on the Arduino default to INPUTs
  pinMode(SegmentD, OUTPUT);
  pinMode(SegmentE, OUTPUT);
  pinMode(SegmentF, OUTPUT);
  pinMode(SegmentG, OUTPUT);
  
  pinMode(Lamp01Pin, OUTPUT); //controls switching transistor
  pinMode(Lamp02Pin, OUTPUT); //controls switching transistor
}
//-----------------------------------------------------------------------
void loop()
//This loop calls the subroutines repeatedly to keep the LEDS lit.
//Make sure you follow this logic completely before continuing.
//Do you understand why two delays are necessary?  One in the mail loop
//and another in the subroutines.
{  //Begin loop
//-----------------------------------------------------------------------
  {
    subNumeralTHREE();   
    subSwitchA();  //turns on LED lamp A, turns off B.
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchB();  //turns on LED lamp B, turns off A.
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralNINE();   
    subSwitchB();
    subPause();
  } 
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------  
  {
    subNumeralEIGHT();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSEVEN();   
    subSwitchB();
    subPause();
  } 
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSIX();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFIVE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFOUR();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTHREE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralNINE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralEIGHT();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSEVEN();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSIX();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFIVE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFOUR();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTHREE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralNINE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralEIGHT();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSEVEN();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralSIX();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFIVE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralFOUR();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTHREE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralTWO();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralZERO();   
    subSwitchA();
    subPause();
  }
//-----------------------------------------------------------------------
  {
    subNumeralONE();   
    subSwitchB();
    subPause();
  }
//-----------------------------------------------------------------------
}  //End loop

//----------------------------------------------------------------------- 
//  SUBROUTINES
//-----------------------------------------------------------------------
void subPause() //inserts a pause between numbers displayed
{
  delay(vDelay); //turns delay into a subroutine call
}
//-----------------------------------------------------------------------
void subSwitchA() //Turns Lamp A on and B off.
{
    digitalWrite(Lamp01Pin,HIGH);
    digitalWrite(Lamp02Pin,LOW);
}
//-----------------------------------------------------------------------
void subSwitchB() //Turns Lamp B on and A off.
{
    digitalWrite(Lamp02Pin,HIGH);
    digitalWrite(Lamp01Pin,LOW);
}
//-----------------------------------------------------------------------
void subNumeralBLANK() //Displays segments representing a blank
{
  digitalWrite(SegmentA, LOW);
  digitalWrite(SegmentB, LOW); //
  digitalWrite(SegmentC, LOW); //
  digitalWrite(SegmentD, LOW);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, LOW);
  digitalWrite(SegmentG, LOW);
}    //End subNumeralBLANK
//-----------------------------------------------------------------------
void subNumeralZERO() //Displays segments representing number "0".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, HIGH);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, LOW);
}    //End subNumeralZERO
//-----------------------------------------------------------------------
void subNumeralONE() //Displays segments representing number "1".
{
  digitalWrite(SegmentA, LOW);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, LOW);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, LOW);
  digitalWrite(SegmentG, LOW);
}    //End subNumeralONE
//----------------------------------------------------------------------- 
void subNumeralTWO() //Displays segments representing number "2".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH); //
  digitalWrite(SegmentC, LOW); //
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, HIGH);
  digitalWrite(SegmentF, LOW);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralTWO
//----------------------------------------------------------------------- 
void subNumeralTHREE() //Displays segments representing number "3".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, LOW);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralTHREE
//----------------------------------------------------------------------
void subNumeralFOUR() //Displays segments representing number "4".
{
  digitalWrite(SegmentA, LOW);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, LOW);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralFOUR
//-----------------------------------------------------------------------
void subNumeralFIVE() //Displays segments representing number "5".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, LOW);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralFIVE
//-----------------------------------------------------------------------
void subNumeralSIX() //Displays segments representing number "6".
{
  digitalWrite(SegmentA, LOW);
  digitalWrite(SegmentB, LOW);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, HIGH);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralSIX
//-----------------------------------------------------------------------
void subNumeralSEVEN() //Displays segments representing number "7".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, LOW);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, LOW);
  digitalWrite(SegmentG, LOW);
}    //End subNumeralSEVEN
//-----------------------------------------------------------------------
void subNumeralEIGHT() //Displays segments representing number "8".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH); //
  digitalWrite(SegmentC, HIGH); //
  digitalWrite(SegmentD, HIGH);
  digitalWrite(SegmentE, HIGH);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralEIGHT
//-----------------------------------------------------------------------
void subNumeralNINE() //Displays segments representing number "9".
{
  digitalWrite(SegmentA, HIGH);
  digitalWrite(SegmentB, HIGH);
  digitalWrite(SegmentC, HIGH);
  digitalWrite(SegmentD, LOW);
  digitalWrite(SegmentE, LOW);
  digitalWrite(SegmentF, HIGH);
  digitalWrite(SegmentG, HIGH);
}    //End subNumeralNINE
//-----------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////
// END MAIN PROGRAM
////////////////////////////////////////////////////////////////////////////

// Key entered by Anton da Bassguy 2011
// Test successfully April 19, 2011
// This code does not test the decimal points on the lamp
// This code intentionally avoids use of arrays and counting loops
// for greater understandability.
// Tested again April 24, 2011
////////////////////////////////////////////////////////////////////////////

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