Archived

This topic is now archived and is closed to further replies.

Seven Segment Display

This topic is 5127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to make a timer counting the time inbetween the start of a puzzle and completion. I can do the actural timing but is it possible to make the timer look like a 7 segment display(like a digital clock)? This is using C with the Win32 API with SOME(a very small amount") of OpenGL.I found one code to do it, in Programming Windows by Charles Petzold, but it takes up a LARGE part of the screen and the whole seven segment display is based on "magic numbers" and it gives no explanation on how to shrink it. This is rare for the book but I re-read the section like 4 times. Can anyone help me?

Share this post


Link to post
Share on other sites
Make a grid for the number. first and last columns are vertical lines, the middle column is the horizontals.

typedef boolean segmentmap[2][3][2] segmentmap_t;

Then, declare and define your numbers, or for that matter the whole 256 ASCII set.

segmentmap_t one, two, three, four
segmentmap_t five, six, seven, eight
segmentmap_t nine, ten, zero // etc.

Then just draw the lines, most simply as plain rectangles, according to the time.

EDIT: or set it up like this:

boolean segmentmap[255][2][3][2];

int i;
for( i=0; i>255; i++ )
{
/* fill in segmentmaps from a file, or constants in the .exe */
}

Then you can just draw segmentmap[ascii_code].

[edited by - mdleadg on November 29, 2003 2:37:55 AM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by MdLeadG
Make a grid for the number. first and last columns are vertical lines, the middle column is the horizontals.

typedef boolean segmentmap[2][3][2] segmentmap_t;

Then, declare and define your numbers, or for that matter the whole 256 ASCII set.

segmentmap_t one, two, three, four
segmentmap_t five, six, seven, eight
segmentmap_t nine, ten, zero // etc.

Then just draw the lines, most simply as plain rectangles, according to the time.

EDIT: or set it up like this:

boolean segmentmap[255][2][3][2];

int i;
for( i=0; i>255; i++ )
{
/* fill in segmentmaps from a file, or constants in the .exe */
}

Then you can just draw segmentmap[ascii_code].

<SPAN CLASS=editedby>[edited by - mdleadg on November 29, 2003 2:37:55 AM]</SPAN>


This is awful and won''t work. MdLeadG is making a 12 element array for 7 elements, that should be a clue that this is flawed. You''d be better off with a single-dimension, 7 element array and constants for each segment. then, expand that for the characters you need from the ascii set, which sounds to be just numbers so thats ascii #48 - #57 (''0''-''9''), if thats all you need, make a [10][7] array, and using 48 as an offset you can easily go from ascii to your 7-segment disply if thats what you want.

Share this post


Link to post
Share on other sites
Sorry, I was AP, forgot to log in.

anyways, to correct myself, I see what McLeadG is attempting to do, and it *could* be made to work. however its wasteful of memory, un-clear, and a horrible mis-use of arrays. Once you have a good representation, you can use GDI, OpenGL or whatever else to render it.


If you really wanted to save memory, you could pack everything into a byte by masking it with bitwise operators. But do it the easy way, one way should be faster, the other will save a tiny amount of memory, neither is worth the trade off on todays PCs so do what''s easy unless you have a good reason.

Ravyne, NYN Interactive Entertainment
[My Site][My School][My Group]

Share this post


Link to post
Share on other sites
quote:
Original post by Ravyne
Sorry, I was AP, forgot to log in.

anyways, to correct myself, I see what McLeadG is attempting to do, and it *could* be made to work. however its wasteful of memory, un-clear, and a horrible mis-use of arrays. Once you have a good representation, you can use GDI, OpenGL or whatever else to render it.


If you really wanted to save memory, you could pack everything into a byte by masking it with bitwise operators. But do it the easy way, one way should be faster, the other will save a tiny amount of memory, neither is worth the trade off on todays PCs so do what''s easy unless you have a good reason.

Ravyne, NYN Interactive Entertainment
[My Site][My School][My Group]

Exactly - I was really tired last night - Doh!

Yes, Ravyne, a boolean[10][7] array would be much better at describing the number set. I can''t believe this easy one flew over my head

Share this post


Link to post
Share on other sites
This similar to what I have. The code I am currently using is below:

nt DisplayDigit (HDC hdc, int iNumber)
{
static BOOL fSevenSegment [10][7] = {
1, 1, 1, 0, 1, 1, 1, // 0
0, 0, 1, 0, 0, 1, 0, // 1
1, 0, 1, 1, 1, 0, 1, // 2
1, 0, 1, 1, 0, 1, 1, // 3
0, 1, 1, 1, 0, 1, 0, // 4
1, 1, 0, 1, 0, 1, 1, // 5
1, 1, 0, 1, 1, 1, 1, // 6
1, 0, 1, 0, 0, 1, 0, // 7
1, 1, 1, 1, 1, 1, 1, // 8
1, 1, 1, 1, 0, 1, 1 } ; // 9
static POINT ptSegment [7][6] = {
7, 6, 11, 2, 31, 2, 35, 6, 31, 10, 11, 10,
6, 7, 10, 11, 10, 31, 6, 35, 2, 31, 2, 11,
36, 7, 40, 11, 40, 31, 36, 35, 32, 31, 32, 11,
7, 36, 11, 32, 31, 32, 35, 36, 31, 40, 11, 40,
6, 37, 10, 41, 10, 61, 6, 65, 2, 61, 2, 41,
36, 37, 40, 41, 40, 61, 36, 65, 32, 61, 32, 41,
7, 66, 11, 62, 31, 62, 35, 66, 31, 70, 11, 70 } ;
int iSeg ;

for (iSeg = 0 ; iSeg < 7 ; iSeg++)
if (fSevenSegment [iNumber][iSeg])
Polygon (hdc, ptSegment [iSeg], 6) ;

return 0;
}

int DisplayTwoDigits (HDC hdc, HWND hwnd, int iNumber, BOOL fSuppress)
{
int DDcheck;

if (!fSuppress || (iNumber / 10 != 0))
DisplayDigit (hdc, iNumber / 10) ;

OffsetWindowOrgEx (hdc, -42, 0, NULL) ;
DDcheck=DisplayDigit (hdc, iNumber % 10) ;
if(DDcheck != 0)
MessageBox(hwnd, TEXT("Display Digit Failed"), TEXT("Display Digit Failed"), NULL);
OffsetWindowOrgEx (hdc, -42, 0, NULL) ;

return 0;
}

int DisplayColon (HDC hdc)
{
POINT ptColon [2][4] = { 2, 21, 6, 17, 10, 21, 6, 25,
2, 51, 6, 47, 10, 51, 6, 55 } ;

Polygon (hdc, ptColon [0], 4) ;
Polygon (hdc, ptColon [1], 4) ;

OffsetWindowOrgEx (hdc, -12, 0, NULL) ;

return 0;
}

int DisplayTime (HDC hdc,HWND hwnd, int time_elapsed)
{
int minutes, seconds, DTDcheck, DCcheck;

minutes = time_elapsed / 60;
seconds = time_elapsed % 60;

DTDcheck=DisplayTwoDigits (hdc, hwnd, minutes, FALSE) ;

if(DTDcheck != 0)
MessageBox(hwnd, TEXT("Display Two Digits Failed"), TEXT("Display Two Digits Failed"), NULL);

DCcheck=DisplayColon (hdc) ;

if(DCcheck != 0)
MessageBox(hwnd, TEXT("Display Colon Failed"), TEXT("Display Colon Failed"), NULL);

DTDcheck=DisplayTwoDigits (hdc, hwnd, seconds, FALSE) ;

if(DTDcheck != 0)
MessageBox(hwnd, TEXT("Display Two Digits Failed on second call"), TEXT("Display Two Digits Failed"), NULL);

return 0;
}



This works perfectly but I want to shrink the clock. It is WAY too big. How excactly can I do that? Can I devide the array by 2(to get 1/4 the size, to get a percent of the total devide each side by the squareroot of the inverse of the fraction percentage of the shape you want)? I think that will translate the picture not shrink it right? How can I shrink it? Also as a side not, why is the array called [6][7] but its [12][7]?
Ray Koons

PS- yes its modified code from a book.

Share this post


Link to post
Share on other sites