Category : C Source Code
Archive   : METER.ZIP
Filename : METER.C

 
Output of file : METER.C contained in archive : METER.ZIP

#include
#include
#include < stdlib.h>

char cpyrit[]="METER Copyrightt (c) 1990 Product Designs";

//declares
#define BLACK_COLOR 0
#define BACK_COLOR 1
#define FORG_COLOR 16
#define FULL_SCALE 100
#define STEP_SIZE 25
#define DISPLAY_SCALE 100
#define STEP_TIME 150
#define WN_MAX 32
#define FOREVER for (;;)

// A structure to contain the control variables for display
typedef struct {
int oldvalue;
int x1;
int x2;
int l;
int b;
int r;
int t;
int w2;
int aw;
} METER;

METER M0 = {0};
METER M1 = {0};
METER M2 = {0};
METER M3 = {0};
METER M4 = {0};
METER M5 = {0};

//prototypes for the display functions
void create_all_meter ( int wn );
void create_meter ( METER *(p), int posx, int posy, int warg, int aarg );
void show_meter ( METER *(p), int value );
int fetch ( int arg );

//now for the main line
main ( )
{
int i, j, o, tmp; // variables
int step;
int wn;


_setvideomode ( _HRES16COLOR ); // ega mode

wn = 2; // the initial frequency ratio

create_all_meter ( wn ); // paint the meter panel

i = 25;

// stroke the meter displays through their full range

FOREVER {
j = fetch ( i );

show_meter ( &M0, j );
show_meter ( &M1, j );
show_meter ( &M2, j );
show_meter ( &M3, j );
show_meter ( &M4, j );
show_meter ( &M5, j );

if ( kbhit () )
{
getch (); // clear the keyboard buffer
wn += wn; // change the natural frequency of the panel
if ( wn < WN_MAX )
{
create_all_meter ( wn );
}
else
break;
}
}

_setvideomode (_DEFAULTMODE );
}

/*
* procedure to return a test value
* this procedure accepts an interger argument whichs
* forms the basis for the return value.
*/

int fetch ( int arg )
{
static int step;
int j;

// simulate a real noisy signal

j = arg;
j += rand ( ) / 6540;

// now add a step function to the signal to show
// long term dynamics

if ( step++ >= STEP_TIME )
{
j += STEP_SIZE;
if ( step++ >= STEP_TIME * 2 )
step = 0;
}
return ( j );
}

// execute a second order filter algorithm
// Note that these four LOC represent
// the reason for this program!!

int filter_meter ( METER *( p ), int value )
{
int out;

out = p-> x1 / p -> w2;
p -> x2 = value + p -> x2 / p -> aw - out;
p -> x1 = p -> x1 + p -> x2;

return ( out );
}

//display a point on the meter.
// Apply the filtering
// Scale the result to the physical full scale
// Clip the number to physical limits
// Blank out the old point
// paint the new line

// this display range is from 0 to 100
// This range if normalized for the physical scale

void show_meter ( METER * ( p ), int value )
{
int v;

// first perform the smoothing operation
v = filter_meter ( p, value );

// now apply the full scale multiplier
v =( v*DISPLAY_SCALE/FULL_SCALE ) + p -> l;

//perform a limiting function here to
// keep the pointer inside the metering area
if ( v < p -> l )
v = p -> l;

if ( v > p -> r )
v = p -> r;

// rub out the current pointer
_setcolor ( BACK_COLOR );
_pie ( _GBORDER, p -> l, p -> b, p -> r, p-> t, v, p -> t, v, p -> t);
p -> oldvalue = v;

// now paint the new pointer

_setcolor ( FORG_COLOR );
_pie ( _GBORDER, p -> l, p -> b, p -> r, p -> t, v, p -> t, v, p -> t );
p -> oldvalue = v; // rember this for contracting out later
}

//procedure to create a panel of meters

void create_all_meter ( int wn )
{
_setcolor ( BLACK_COLOR );
_clearscreen ( _GCLEARSCREEN );

// create the reference meter
create_meter ( &M0, 100, 50, 1, 1 );
create_meter ( &M1, 300, 50, wn, 2 );
create_meter ( &M2, 500, 125, wn, 4 );

create_meter ( &M3, 100, 125, wn, 8 );
create_meter ( &M4, 300, 125, wn, 32 );
create_meter ( &M5, 500, 125, wn, 64 );

_settextposition ( 22, 30 );
printf ( " OUT = X1 / %2u", wn * wn );

_settextposition ( 23, 30 );
printf ( " X2 = IN + X2 / Q %2 - OUT", wn );

_settextposition ( 24, 30 );
printf ( "X1 = X1 + X2" );

_settextposition ( 25, 10 );
printf ("Type a space ");
}

// procudure to create one meter
// Initialize the meter location variables
// and paint the meter display
// p points to a METER structure instance
// posx is the meter X axis position argument
//posy is the meter Y axis position argument
//warg = Fs/Wn sampling frequency to natural frequency ratio
// aarg = Q* (Fs/Wn ) damping factor control = 1/2 * Q

void create_meter ( METER * ( p ), int posx, int posy, int warg, int qarg )
{
// First fill in the meter array data
p -> l = posx - DISPLAY_SCALE / 2;
p -> b = posy + 30;
p -> r = posx + DISPLAY_SCALE /2;
p -> t = posy - 30;
p -> oldvalue = p -> l;
p -> w2 = warg * warg;
p -> aw = ( warg * qarg ) / 8;
if ( p ->aw == 0 ) p -> aw++; // Force a stable filter algorithm
p -> x1 = 0;
p -> x2 = 0;

_setcolor ( BACK_COLOR ); // Setup the background

//Now paint the meter outline
_pie ( _GFILLINTERIOR, p -> l, p -> b, p->r, p->t, p->r, p ->t, p->l, p->t );

// identify the filter parameters
_settextposition ( p->b/8-2, 0+p->l/8 );
printf ("F/W = %2u Q = %4.2f", warg, (double) qarg/8 );

_settextposition ( 1 + p -> b/8-2, 0 + p -> l / 8 );
printf ( "(F/W) ^2 = %2u Q*F/W=%2u", p->w2, p->aw);

// paint the zero pointer
show_meter ( p, 0 );
}