7-Segment display with printf and multidimensional array for segments

OMG-1 picture OMG-1 · Oct 17, 2011 · Viewed 8.1k times · Source

In K.N Kings "C programming: A modern approach", chapter 10 exercise 7, the task is to make a digit converter from normal digits to 7-segment digits in ASCII art, like this:

   _   _        _   _   _   _   _   _ 
|  _|  _|  |_| |_  |_    | |_| |_| | |
| |_   _|    |  _| |_|   | |_|   | |_|

I got the sequence for each digit where to turn in it on and off

sample:

int digit_sequence[10][7] = {
    // A,B,C,D,E,F,G
    /* 0 */ {1,1,1,1,1,1,0}

}

Where 1 = ON, 0 = OFF

but I have a hard time getting the process_digit(int digit, int position) function to work.

I have a hard time in my head translating from sequence[10][7] to digits[4][MAX_DIGITS*4]

Could a kind soul please help me?

I have been reading the golf code seven-segment challenge, but even though I understand that theory it's still hard to convince my brain into doing what I want with multiple arrays.


Ignoring the ASCII art, the question reads:

Write a program that prompts the user for a number and then displays the number using characters to simulate the effect of a seven-segment display.

...

Characters other than digits should be ignored. Write the program so that the maximum number of digits is controlled by a macro named MAX_DIGITS which has the value 10. If the number contains more than this number of digits, the extra digits are ignored. Hints: Use two external arrays. One is the segments array [...] which stores data representing the correspondence between digits and segments. The other array, digits, will be an array of characters with 4 rows (since each segmented digit is 4 characters high) and MAX_DIGITS * 4 columns (digits are three characters wide but a spaces is needed between digits for readability). Write your program as four functions: main, [...]

void clear_digits_array(void);
void process_figit(int digit, int position);
void print_digits_array(void);

clear_digits_array will store blank characters into all elements of the digits array. process_digit will store the seven-segment representation of digit into a specified position in the digits array (positions range from 0 to MAX_DIGITS - 1). print_digits_array will display the rows of the digits array, each on a single line [...].

Answer

Thiago Curvelo picture Thiago Curvelo · Oct 28, 2011

The trick is to map where a segment goes on display.

The line number is the same for each segment.

0:  _   _
1: |_| |_| ...
2: |_| |_|
3:     

However, the columns vary by position. Each position is a 4 characters width 'mini-matrix' (3 for segments and 1 for space: '|_| '). So we fix the line of segment and sum its column on the 'mini-matrix' with (position*4).

0123 4567 89AB
 _    _    _
|_|  |_|  |_|   ...
|_|  |_|  |_|
pos0 pos1 pos2

Got it? The code will be something like that:

void process_digit(int digit, int position){
    int i;
    for(i=0;i<7;i++){
        if(segments[digit][i]==1) /* Has digit the i segment? */
            switch(i){
                case 0: digits[0][1+position*4]='_';break;
                case 1: digits[1][2+position*4]='|';break;
                case 2: digits[2][2+position*4]='|';break;
                case 3: digits[2][1+position*4]='_';break;
                case 4: digits[2][0+position*4]='|';break;
                case 5: digits[1][0+position*4]='|';break;
                case 6: digits[1][1+position*4]='_';break;
            }
    }
}

(You may choose between '-' and '_', or perhaps change some lines)

Hope it helps.