Click here to Skip to main content
Email Password   helpLost your password?
Screenshot - screen_shot.png

Introduction

This article describes an approach to constructing a cool segmented LED displayer that is similar to the LEDs used in alarm clocks and industry monitors. This control can be used to display time, numerical values and even some English characters. I hope it will be helpful in programs such as hardware simulators.

Background

In this section, I would like to give a brief introduction to the ideas behind this control. In a 7-segment LED displayer, one character is composed of at most 7 segments, as in the picture shown below.

Figure 1 - 7 segments

Figure 1: Segmented character

Each segment has the following properties: the width of the segment, the bevel rate of the corners in the segment and the interval between segments.

Figure 2 - 1 segment

Figure 2: Properties of each segment

If we mark those 7 segments with numbers, as the picture shows in Figure 1, then we can use indices to represent different characters. For example, the character "1" can be represented as (2, 3) and the character "5" can be represented as (1, 6, 7, 3, 4). To draw the whole scene, we should first calculate the bound rectangles where a certain character is drawn. Then the segments in each specified bound rectangle should be drawn. The algorithm for drawing a 7-segmented LED character in a specified bound rectangle is shown in Figure 3.

Figure 3 - Algorithm

Figure 3: Drawing one character

Using the code

This control is quite easy to use. Just drag it from the toolbox to your form in design mode. Then adjust its provided properties in the designer or at runtime to modify its appearance. The properties are listed in the table below:

BorderWidth int Get or set the width of the border around the control.
BorderColor System.Color Get or set the color of the border around the control.
HighlightOpaque byte Get or set the opaque value of the highlight. 0 implies that the highlight will end transparent, while 100 implies that the highlight will keep its transparency from the beginning.
ShowHighlight bool Get or set a value indicating whether to show the highlight area on the control. If it is set to false, the value of the HighlightOpaque property is ignored.
CornerRadius int Get or set the corner radius for the control. If RoundCorner equals false, the value of this property is ignored. The valid value is from 1 to 10.
GradientBackground bool Get or set a value indicating whether the background was filled in gradient colors.
BackColor_1 System.Color Get or set the first background color. If GradientBackground equals true, this color will be the color at the top of the background rectangle. Otherwise, this color will be the solid background color.
BackColor_2 System.Color Get or set the second background color. If GradientBackground equals true, this color will be the color at the bottom of the background rectangle. Otherwise, this color will be ignored.
RoundCorner bool Get or set the border style. If it is true, the border of the control will be a round rectangle. Otherwise, the border is a normal rectangle.
SegmentIntervalRatio int Get or set the segment-interval ratio. The larger this value is, the wider the gaps between segments are.
TextAlignment Alignment Get or set the alignment style of the text.
SegmentWidthRatio int Get or set the segment-width ratio. The larger this value is, the wider the segments are.
TotalCharCount int Get or set the total number of characters to display. If the number of characters contained in the displaying text is larger than this value, the displaying character will be truncated.
BevelRate float Get or set the bevel rate of each segment. Please refer to Figure 2 for further information.
FadedColor System.Color Get or set the color of faded background characters.
Text string Get or set the text of the control.

Points of Interest

A control at presentation level may do lots of painting. Most of the time, the control has to be repainted when one of its properties is changed. This may cause multiple invalidating if several properties of the control are changed in quick succession. In order to avoid multiple painting, we can implement the ISupportInitialize interface in our control. First, we set a member variable in the BeginInit() method.

private bool m_bIsInitializing = false;
void ISupportInitialize.BeginInit()
{
    m_bIsInitializing = true;
}

Then we rewrite our properties in the following manner:

public Color FadedColor
{
    get
    {
        return m_colFadedColor;
    }
    set
    {
        if (m_colFadedColor == value)
        return;
        m_colFadedColor = value;
        // check if the control is in initializing mode
        if (!m_bIsInitializing)
        {
            Invalidate();
        }
    }
}

At last, in the EndInit() method, we turn off the initialization mode and repaint the control.

void ISupportInitialize.EndInit()
{
    m_bIsInitializing = false;
    Invalidate();
}

Now we can use batch initialization to prevent successive painting of the control.

((System.ComponentModel.ISupportInitialize)mycontrol).BeginInit();
mycontrol.BackColor = System.Drawing.Color.Transparent;
mycontrol.BackColor_1 = System.Drawing.Color.Black;
mycontrol.BackColor_2 = System.Drawing.Color.Transparent;
mycontrol.BevelRate = 0.5F;
mycontrol.BorderColor = System.Drawing.Color.White;
mycontrol.FadedColor = System.Drawing.Color.Black;
((System.ComponentModel.ISupportInitialize)mycontrol).EndInit();

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralGreat control!
blandwehr
8:10 13 Nov '08  
Very nice. I've been in the process of developing my own 7 segment LED control for a project I'm working on and ran across your control. Lots of thought and effort went into this. Wonderful job! Smile
GeneralThis is great
Nicholas Piasecki
8:52 28 Aug '08  
Good work! Smile
GeneralLastest code on CodePlex
Liu Xia
23:12 10 May '08  
This project has been moved to CodePlex. http://www.codeplex.com/7segledcontrol[^]
GeneralBut it's user hostile!
PIEBALDconsult
14:58 8 May '08  
I can't read it, I can't copy and paste.
GeneralRe: But it's user hostile!
Liu Xia
22:45 8 May '08  
I'm sorry, I don't quite catch itConfused ~ do you mean that you want to copy the text on the control?
This control is just for presentation only. OK, say, do you think such component on a real machine is used for input? If it really is, an input keyboard should be used instead of directly editing on the LED Smile

modified on Friday, May 9, 2008 9:18 AM

GeneralRe: But it's user hostile!
PIEBALDconsult
13:28 9 May '08  
Liu Xia wrote:
do you mean that you want to copy the text on the control?

Yes, I should be able to copy the value and paste it into something else.
GeneralRe: But it's user hostile!
Liu Xia
18:55 9 May '08  
Thanks for your reply! I will work on it and update the downloads as soon as possible Smile
AnswerRe: But it's user hostile!
Liu Xia
20:10 9 May '08  
The updated downloads are sent to the editor. Many thanks to PIEBALDconsult Smile ! The download link might be updated the day after tomorrow.

Update:

(1) The text on the control now can be copied to clipboard.
(2) The color of the control border will change (defined by user) when the control has focus.
(3) Bug fixed: The anti-alias effect disappears when the bound is a regular rectangle.

----- Wellcome to Beijing for the summer Olympics Smile -----
GeneralRe: But it's user hostile!
Bruce Munck
3:18 11 Jul '08  
Maybe I'm missing something, but if the program sends information to the LED for display then that value is already contained in a variable. Reading it from the LED would add another step to the process and seems redundant. But, thanks for adding more functionality to the control!
GeneralSome letters don't render
Manster
12:39 8 May '08  
First let me say this is a great control. When using the control, I noticed that the following English letters don't render; K, W, and X.

How do I get these letters to render?

Thanks
GeneralRe: Some letters don't render
Liu Xia
22:43 8 May '08  
Thanks for your question. Yes, this control is currently a 7-segment led displayer and there are some letters that can't be rendered, e.g. 'K' or 'X' or 'W'.
GeneralPassword?
KnightRohan
2:34 11 Jan '08  
Hi,
I'm trying to use this project in VS2005, but i receive a message 'import key file' and need to fill in a password (file LedctlKey.pfx). Could you please give us the password?

Thanks.
AnswerRe: Password?
Liu Xia
16:10 30 Jan '08  
I'm sorry for the inconvenience. In fact, you can create a empty project and add the source into it, or using the password 'detectiveconan' in the project downloaded.
Generalsuperb
erdm
1:48 7 Dec '07  
thx a lot
GeneralGreat documentation
MAEI
13:16 29 Nov '07  
What did you use to generate the grapics in your article... This is what is really impressive, the clarity and ease of which each of your pictures describes visibly what is happening in your UI drawing functions.

wahoo

GeneralBUG in setter of Text
KenGuru
3:54 4 Sep '07  
I'm setting the Text with a timer every second to simulate a clock. Each time I set the Text my memory is growing.
I tried to debug, but I can't get it start, because I don't know the password of the key file.

Live is to short to be angered about lost chances!

GeneralRe: BUG in setter of Text
Liu Xia
19:01 7 Sep '07  
Hi KenGuruSmile
Thanks for your reply! But in dotNet framework, even you call dispose for the object which implements the IDisposable interface, the resource of the object may be just marked, not collected. The GC will collect them when it is necessary to do that.
Sorry for the strong named key:(. but you can just create a new project and copy the source file into it.
Generalawesome
Antom
14:50 1 Sep '07  
awesome work
GeneralVery Nice
SpiveyC#
5:59 23 Aug '07  
I really liked this. Good article.
GeneralDefine char with table
NicolaBitonto
18:59 26 Jul '07  
You may defines ASCII char with table as:
const int Sa = 0x01; // ....Sa....
const int Sb = 0x02; // Sf......Sb
const int Sc = 0x04; // ....Sg....
const int Sd = 0x08; // Se......Sc
const int Se = 0x10; // ....Sd......Sh
const int Sf = 0x20;
const int Sg = 0x40;
const int Sh = 0x80;

static char[] Tcar =
{
'1' , '2' , '3' ,
'4' , '5' , '6' ,
'7' , '8' , '9' ,
'0' , 'A' , 'B' ,
'C' , 'D' , 'E' ,
'F' , '.' , ' ' ,
'H' , 'I' , 'L' ,
'O' , 'P' , 'R' ,
'U' , '-' , '=' ,
'a' , 'b' , 'c' ,
'd' , 'e' , 'f' ,
'h' , 'i' , 'n' ,
'o' , 'r' , 't' ,
'u'
};

static int[] Tval =
{
Sb+Sc, Sa+Sb+Sd+Se+Sg, Sa+Sb+Sc+Sd+Sg,
Sb+Sc+Sf+Sg, Sa+Sc+Sd+Sf+Sg, Sa+Sc+Sd+Se+Sf+Sg,
Sa+Sb+Sc, Sa+Sb+Sc+Sd+Se+Sf+Sg, Sa+Sb+Sc+Sd+Sf+Sg,
Sa+Sb+Sc+Sd+Se+Sf, Sa+Sb+Sc+Se+Sf+Sg, Sc+Sd+Se+Sf+Sg,
Sa+Sd+Se+Sf, Sb+Sc+Sd+Se+Sg, Sa+Sd+Se+Sf+Sg,
Sa+Se+Sf+Sg, Sh, 0x00,
Sb+Sc+Se+Sf+Sg, Se+Sf, Sd+Se+Sf,
Sc+Sd+Se+Sg, Sa+Sb+Se+Sf+Sg, Se+Sg,
Sc+Sd+Se, Sg, Sd+Sg,
Sa+Sb+Sc+Se+Sf+Sg, Sc+Sd+Se+Sf+Sg, Sa+Sd+Se+Sf,
Sb+Sc+Sd+Se+Sg, Sa+Sd+Se+Sf+Sg, Sa+Se+Sf+Sg,
Sc+Se+Sf+Sg, Se, Sc+Se+Sg,
Sc+Sd+Se+Sg, Se+Sg, Sd+Se+Sf+Sg,
Sc+Sd+Se
};

So, your DrawSingleChar() Procedure becomes:
private void DrawSingleChar(Graphics g, Rectangle rectBound, Color colCharacter, char car, float bevelRate, float segmentWidth, float segmentInterval)
{
int emme = Tcar.Length;
int i;
for (i = 0; i < emme; i++)
{
if (Tcar[i] == car)
{
int segm = Tval[i];

for (int k = 0; k < 8; k++)
{
if ((segm & (1 << k)) != 0)
{
DrawSegment(g, rectBound, colCharacter, k+1, bevelRate, segmentWidth, segmentInterval);
}
}
break;
}
}
}

And DrawSingleCharWithFadedBk() becomes:
private void DrawSingleCharWithFadedBk(Graphics g, Rectangle rectBound, Color colCharacter,
Color colFaded, char car, float bevelRate, float segmentWidth, float segmentInterval)
{
int emme = Tcar.Length;
int i;
for (i = 0; i < emme; i++)
{
if (Tcar[i] == car)
{
int segm = Tval[i];

for (int k = 0; k < 8; k++)
{
if ((segm & (1 << k)) != 0)
{
DrawSegment(g, rectBound, colCharacter, k + 1, bevelRate, segmentWidth, segmentInterval);
}
else
{
DrawSegment(g, rectBound, colFaded, k + 1, bevelRate, segmentWidth, segmentInterval);
}
}
break;
}
}
}

Ciao

Nicola
GeneralRe: Define char with table
YouMiss
15:52 27 Nov '07  
Hey, just saw this.

I believe that I learnt this 7-segment led display when I was doing some native C programming for DIP micro processor back to my college time.

Nice binary manipulation, inspiring.

Someone was born greatness;
Someone achieved greatness;
Someone have the greatness thrust upon him;

GeneralRe: Define char with table
jinfd
8:55 12 May '08  
yeah, i quite agree with your habit of coding. i will prefer "Array.IndexOf()"   to instead of the linear searching loop .
GeneralLED Control
moegoe
3:17 24 Jul '07  
Hi guys,
i am new at programming so please bear with me.
i downloaded the demo project and i am trying to the run the project using VS 2005,
when doing so i get prompted for a password.

Please Help
GeneralRe: LED Control
Liu Xia
2:08 27 Jul '07  
Sorry for the late reply!
Well, it is strange~~ and I can't reproduce your problem. However, you can download the source code and re-compile the project to see if it can be used.Smile
GeneralGood work...!
Chamadness
1:35 24 Jul '07  
Thanks for the good work and also for sharing!
Good work also on the presentation (Article).

Keep it up and optimizations are welcome Wink

CodeMadness - Code before you go mad!


Last Updated 12 May 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010