Hello,

I am a first year computing AS student coding a petrol pump program. You can see the specification here. I am a little stuck and I was wondering if anyone could point me in the right direction. I have coded a seven segment display using arrays, procedures, write lines and gotoxy's. You can see my code below.

But I am unsure of how to implement this seven segment display into my code. What I am trying to do is when the program runs I want the display to start running, kind of like a timer. I want the display to increment by 1 from 00.0 to 01.1,02.2,03.3 etc etc but I am unsure of how to implement this. Can someone point me in the right direction ?

PROGRAM segcode;
USES WINCRT;

VAR

   seg: array[1..7] of char;
   a, b, c, d: integer;

{Fills arrays for 7 segment display}
PROCEDURE segassign;
BEGIN;

seg[1] := '_';
seg[2]:= '|';
seg[3]:= '|';
seg[4]:= '-';
seg[5]:= '|';
seg[6]:= '|';
seg[7]:= '¯';


END;

PROCEDURE numberzero;
BEGIN;

      GOTOXY(a+1,b+0);
      WRITELN(seg[1]);
      GOTOXY(a+0,b+1);
      WRITELN(seg[2]);
      GOTOXY(a+2,b+1);
      WRITELN(seg[3]);
      GOTOXY(a+0,b+2);
      WRITELN(seg[5]);
      GOTOXY(a+2,b+2);
      WRITELN(seg[6]);
      GOTOXY(a+1,b+3);
      WRITELN(seg[7]);

END;

BEGIN

     segassign;  {Assign Segments}

     a:= 30;    {provide placements}
     b:= 3;
     numberzero; {zero}

     a:= 34;    {provide placements}
     b:= 3;  
     numberzero; {zero}  

     a:= 38; {provide placements}
     b:= 3;
     numberzero; {zero}
END.

You are on the right track, but you need to think about what each segment should look like.
For example, you could use 4 by 3 character grids for each segment, and the numbers as

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

All segments would be:

_  
|_| 
|_|.

All you need to know is the upper-left hand coordinate. For example, to display a zero:

procedure zero( x, y: integer; dp: boolean );
  begin
  gotoxy( x, y    );  write( ' _  ' );
  gotoxy( x, y +1 );  write( '| | ' );
  gotoxy( x, y +2 );  write( '|_|' );
  if (dp) write( '.' ) else write( ' ' )
  end;

Notice how I added a condition to draw that decimal point.

If you want to treat it as if it were an actual 7-segment display, you could write just one procedure to display it:

procedure draw7seg( x, y: integer; bits: byte );
  begin
  gotoxy( x, y );
  write( ' ' );
  if bits and $01 then write( '_' ) else write( ' ' );
  write( '  ' );
  gotoxy( x, y +1 );
  { finish filling in the correct code here}
  end;

The bits would be bit zero for A, bit one for B, ..., bit 6 for G, and bit 7 for DP.

The codes for the numbers are easily stored in a const lookup table:

const
  segment_codes: array[ 0..9 ] of byte = (
    $3F, $06, $5B, ... {fill in the remaining codes here}
    );
  segment_dp = $80;

Now you can display a segment knowing both the lookup and the position:

{ Draw a seven with a decimal point next to it at (x,y) = (10,5) }
draw7seg( 10, 5, segment_codes[ 7 ] +segment_dp );

Er, I've got to go. Hope this helps.

Hey there,

First off I would like to thank you for your help. Sorry the late reply, I have been working on other aspects of the project and now I am ready to fully start on the LCD.

I have been looking through your code. There are some bits I do not understand. Mainly the parts about bits and the constant lookup table. "$3F, $06, $5B" What do these refer to ?

"The bits would be bit zero for A, bit one for B, ..., bit 6 for G, and bit 7 for DP."

Also, I have written a procedure that dispenses fuel (this is part of a bigger program):

PROCEDURE givefuel;
BEGIN;
count:=0;
 WRITELN('Press and hold Y to give fuel');
  ch:= readkey;
IF ch='y' THEN
BEGIN
  REPEAT
   count:=count+0.1;
    GOTOXY(5,7); 
      IF count > 100.0 THEN 
          BEGIN
           WRITELN('STOP!');
           HALT(1);
          END;
       WRITE('Fuel dispensed: ', count:0:1);
     ch:=readkey;
  UNTIL (ch<>'y') AND (count >= 0.5); 
 WRITELN;
 WRITELN;
WRITELN('Total Dispensed is: ', count:0:1, ' Litres');
{***REMOVED***}
END
ELSE
BEGIN
WRITELN('Invalid Character Entered!');
HALT(1);
END;
 
END;

I still cannot figure out how to redesign this code and dump it onto a seven segment display. Sorry for all the questions... I am really confused haha.

For the constant lookup table, you first must know about a 7-segment display. Bit 0 is A, bit 1 is B, bit 2 is C, etc.

If you still can't get your head around that, don't worry about it. Just write ten separate procedures to display each digit.

The tough part is that you need a timer and an event loop. You can simulate them. Here is a little TP4 program that demonstrates it:

uses DOS, CRT;

procedure display( x: integer );
  { This routine draws whatever it is }
  { that you are displaying on the screen. }
  { In your case, it should update the 7- }
  { segment displays. }
  { (In my case, it just draws a silly number.) }
  begin
  gotoxy( 1, 1 );
  writeln( x );
  end;

function time: longint;
  { This routine returns the current time represented }
  { in hundredths of a second. In other words, 12:01 }
  { AM would be represented as 100. 12:02 as 200. Etc. }
  var h, m, s, s100: word;
  begin
  gettime( h, m, s, s100 );
  time := s100 +(s *100) +(m *600) +(h *600 *24)
  end;

var
  timeout: longint;
  i: integer;
  c: char;

begin
  { My 'i' variable is just to show the user that }
  { something is happening while waiting for a }
  { keypress. }
  { You will probably want to display the number }
  { of liters dispensed and the total cost so far. }
  i := 1;

  clrscr;
  display( i );
  writeln( 'press any key to stop' );

  { Every two seconds I update 'i'. }
  timeout := time +200;
  repeat
    if time > timeout then
      begin
      { At least two seconds have elapsed. }
      { Update 'i' and display its current }
      { value. Reset to update again two }
      { seconds from now. }
      inc( i );
      display( i );
      timeout := time +200
      end
  until keypressed;

  { read the key that was pressed }
  c := readkey;

  { tell the user we're done }
  writeln;
  writeln( 'goodbye' )
end.

Keep in mind that this program will appear to stop responding if you run it around midnight... (but you can still stop it by pressing any key).

The idea, then, is to make yourself a procedure (you have named it "givefuel") that goes into a loop with the following characteristics:

  • It stops when a key is pressed
  • It polls the current time and causes an event to happen at specific intervals.

The event, of course, is to increment the variable 'fuel_dispensed' (or whatever you name it. "count" is not a good name).

Hope this helps.

Excellent code sample. Thanks ! I will work on this and report back.

Again thanks a lot for your help.

This article has been dead for over six months. Start a new discussion instead.