EFY December 2002
PC-BASED OSCILLOSCOPE
    M.M. VIJAI ANAND                                tive side itself, so both the half cycles are   whether the cycle is positive or negative.
                                                    read as positive when it is given as input to   It is the most critical part of the circuit
    T
            his circuit conditions different sig-   the ADC. During positive half cycle, diode      and if it operates improperly, the symme-
            nals of frequency below 1 kHz and       D3 is on and diode D4 is off, and op-amps       try of the analogue signal displayed in the
            displays their waveforms on the PC’s    A1 and A2 act as inverters. Thus the output     PC monitor gets affected. At the zero-cross-
    screen. The hardware is used to condition       is a replica of the input. During the nega-     ing instant when the input signal transits
    the input waveform and convert it to the        tive half cycle, diode D3 is off and diode D4   to negative side, the zero-crossing detec-
    digital format for interfacing to the PC. The   is on. With R2=R3=R4=R5=R6=R=330                tor informs the PC by taking pin 15 of 25-
    software for acquiring the data into the PC     ohms, the voltage (V) at output pin 1 of op-    pin ‘D’ connector of the parallel port high.
    and displaying the same on its screen is        amp A1 is related to the input voltage (Vi)     The input at pin 15 of ‘D’ connector goes
    written in Turbo C.                             as follows:                                     low when the input signal transits to posi-
        The input waveform (limited to 5V               Vi/R +V/(2R)+V/R=0                          tive side. The zero-crossing detector com-
    peak-to-peak) is first applied to a full-wave       V= -(2/3)Vi                                 municates with the PC through bit D3 of
    rectifier comprising op-amps A1 and A2              The final output voltage (Vo) at pin 7      the status port 379Hex.
    of quad op-amp LM324 (IC4) and a zero-          of op-amp A2 is given by the following               The zero-crossing detector has been
    crossing detector built around LM3914 dot/      relationship:                                   realised using LM3914 IC. You may adjust
    bar display driver (IC8) simultaneously.            Vo=(1+R/2R)(-2Vi/3)= -Vi                    VR1 such that the last LED (LED10) goes
        The full-wave rectifier rectifies the in-   As Vi is negative, the output voltage is        off when the input signal transits negative
    put signal such that the negative half cycle    positive.                                       side of the input waveform. The LM3914
    of the input signal is available in the posi-       The zero-crossing detector detects          itself rectifies the input signal and allows
                    PARTS LIST                   input voltage to 8-bit digital output. The        control port address is 0x037a. The port
Semiconductors:                                  data bus is tristate buffered. With eight         addresses for parallel ports are summarised
IC1             -   74244                        bits, the resolution is 5V/255 = 19.6 mV.         below:
IC2             -   7805
IC3             -   ADC 0804                          The inbuilt clock generator Printer          Data port    Status port      Control port
IC4, IC5        -   LM324                        circuit produces a frequency of
IC7             -   CD4016
IC8             -   LM3914                       about 640 kHz with R1=10 kilo- LPT1                0x0378        0x0379           0x037a
T1              -   Transistor SL100             ohms and C4=150 pF, which are LPT2                 0x0278        0x0279           0x027a
D1-D4           -   1N4001 switching diode
L1-L10          -   Red LED                      the externally connected timing LPT3               0x03bc        0x03bd           0x03be
Resistors (all ¼-watt, ±5% carbon,               components. The conversion
unless stated otherwise):                        time obtained is approximately 100 µs. The             (EFY Lab note. For details of the par-
R1               - 10kilo-ohm
R2-R6            - 330-ohm                       functions of other pins are given below:          allel port pins, refer ‘PC-based Dial Clock
R7               - 1Mega-ohm                          Pin 1 (CS): This is active-low chip-         with Timer’ project published in June 2002
R8-R17           - 470-ohm
R18              - 1kilo-ohm                     select pin.                                       issue of EFY.)
R19              - 10kilo-ohm/1watt                   Pin 2 (RD): This active-low pin en-               The software, written in C program-
VR1, VR2         - 10kilo-ohm Preset
                                                 ables the digital output buffers. When high,      ming language, is user-friendly and easy-
Capacitors:
C1              -   1000µF, 25V electrolytic
                                                 the 8-bit bus will be in Hi-Z state.              to-understand. It gets data from the devel-
C2              -   0.1µF, ceramic                    Pin 3 (WR): This active-low pin is used      oped hardware circuit and displays it in
C3              -   1500PF, ceramic
C4              -   150PF, ceramic               to start the conversion.                          the graphical screen with some changes.
Miscellaneous:                                        Pin 9 (Vref/2): This is optional input            The C program includes two user-de-
25 PIN D-Connector Female                        pin. It is used only when the input signal        fined functions with the main function:
2 PIN SIP CONNECTOR                              range is small. When pin 9 is at 2V, the          graphics( ) and settings( ). The settings( )
PCB
                                                 range is 0-4V, i.e. twice the voltage at pin 9.   function is used to adjust the voltage and
only positive half of the cycle.                      Pin 6 (V+), Pin 7(V-): The actual in-        time scale. The graphics( ) function is used
    The output from the full-wave rectifier      put is the difference in voltages applied to      to display the waveform on the screen. The
is applied to the input of a sample-and-hold     these pins. The analogue input can range          sample control signal is used to close the
circuit comprising op-amps A3 and A4 of          from 0 to 5V.                                     switch in the sample-and-hold circuit, so
the LM324 (IC5), capacitor C3, transistor             In this circuit, pins 1 and 2 are always     the capacitor charges towards the analogue
T1 (SL100), and analogue switch IC6              made low, so the IC and the buses are             input voltage. After the sampling is over,
(CD4016). This circuit samples the input         always enabled. Pin 9 is made open, as            the switch is opened using the same signal.
signal, i.e. it divides the waveform into a      we use analogue input with 0-5V range.            Then the start-of-conversion control signal
number of voltages or points and inputs          Pin 7 is grounded.                                is given to start the conversion. The sam-
each voltage level (with a delay) to the              Pin 5 (INTR): This active-low pin indi-      pling time is approximately 20 µs and the
ADC for conversion into the digital format.      cates the end of conversion. It is connected      conversion time is approximately 100 µs.
Op-amps A3 and A4, along with a switch           to pin 17 (bit D3 of I/O port 37A) of ‘D’              After the conversion is over, the 8-bit
from IC CD4016 and a 1500pF capacitor            connector. (Note that this bit is inverted.)      binary data for the specific voltage sample
with sampling time of 20 µs, are used as              The start-of-conversion command via          is available in the data bus of the ADC.
voltage followers/buffers.                       pin 16 of ‘D’ connector is applied to pin 3       Since the PC accepts only 4-bit data through
    When the base of transistor T1 is made       of the ADC0804. Since we cannot read 8-           the status port (379H), the 8-bit data must
low via strobe pin 1 (bit Do of I/O port         bit digital data output from ADC through          be split into two 4-bit data, which are
37A) of 25-pin D connector of the parallel       the 4-bit status port at a time, we divide it     accepted one after another. This is done by
port, the transistor stops conducting and        in two 4-bit parts and read. Hence the            IC 74244, which is controlled by D0 and D7
the voltage at its collector goes high. The      ADC data output is multiplexed through            bits of the data port. Then the two 4-bit
high voltage at the collector of transistor      two 4-bit sections of octal buffers of IC1        data are packed to get the final 8-bit data.
T1 closes the switch inside CD4016. As a         (74244) with the help of output-enable sig-            The default BGI directory path is set as
consequence, the analogue input signal is        nals from pins 2 and 9 of ‘D’ connector to        ‘c:\tc\bgi’. The sampling time is decided
applied to the capacitor, which charges          pins 1 and 19 (OE1 and OE2, respectively)         by the ‘for’ loop that uses the samp value.
towards the signal voltage.                      of IC1. The digital data output from IC1          The maximum delay produced should be
    When the switch is subsequently              is interfaced to the PC via pins 13 (S4), 12      greater than 20 µs, which is the maximum
opened by applying a logic-high voltage          (S5), 10 (S6), and 11 (S7) of status input        acquisition time of the capacitor. When the
from pin 1 of ‘D’ connector to the base of       port 379H of ‘D’ connector.                       sample value is increased, the number of
transistor T1, the capacitor retains the volt-        The circuit uses 9V and 5V regulated         points on the input signal decreases and
age with a loss of about 20 mV/sec and           DC supply voltages as shown in the cir-           therefore the accuracy decreases. The time
this voltage is given to input pin 6 of the      cuit diagram.                                     scale may be calibrated with 50Hz sine
ADC0804 (IC3) via buffer A4 for conver-               A PC printer port is an inexpensive          wave as reference.
sion to the digital format. When the num-        platform for implementing low-frequency                Note. Mount a 25-pin D-type female
ber of sampling points in the input signal       data acquisition projects. Each printer port      connector on the PCB. Use 25-pin ‘D’ male-
waveform is increased, the reconstructed         consists of data, status, and control port        to-male connector for connecting PCB to
waveform becomes more accurate.                  addresses. These addresses are in sequen-         computer’s female 25-pin LPT port ‘D’ con-
    The ADC0804 is compatible with mi-           tial order; for example, if the data port         nector. It is a demo PC based oscilloscope
croprocessors. It is a 20-pin IC that works      address is 0x0378, the corresponding sta-         only and may not be suitable for real time
with 5V supply. It converts the analogue         tus port address is 0x0379 and the                application.
                                                   PROGRAM IN ‘C’ FOR PC OSCILLOSCOPE
  /* PROGRAM FOR PC OSCILLOSCOPE */                           may=getmaxy();                                              outtextxy(10,170,”TYPE ‘C’ TO CHANGE AND ‘D’ TO
  /*by M.M.VIJAI ANAND B.E (E.E.E) C.I.T */                   may=may-20;                                               DEFAULT”);
  #include<dos.h>                                             outtextxy(0,may,”OSCILLOSCOPE”);                            c=getch();
  #include<time.h>                                            settextstyle(0,0,1);                                        if(c==’c’)
  #include<stdio.h>                                           setcolor(BLUE);                                             {
  #include <graphics.h>                                       outtextxy(max-200,may+2,”press ‘a’ for next sample”);       outtextxy(10,200,”TYPE 1 for 1 unit = 2 volt”);
  #include<string.h>                                                                                                      outtextxy(10,240,”TYPE 2 for 1 unit = 4 volt”);
  #include<stdlib.h>                                          setcolor(BROWN);                                            outtextxy(10,300,”TYPE 3 for user defined”);
  #define data 0x0378                                         outtextxy(max-200,may+10,”press any key to exit”);          switch(getch())
  #define stat 0x0379                                         setcolor(GREEN);                                            {
  #define cont 0x037a                                         settextstyle(0,0,0);                                          case ‘1’ :
                                                              for(a=0;a<=may;a+=get)                                                    { scale=2;
 void graphics(int[],int[]);   //FUNCTION TO DISPLAY          {line(0,a,800,a);                                                          break;
GRAPH AND WAVEFORM                                            }                                                                         }
                                                              for(a=0;a<=max;a+=get)                                        case ‘2’ :
 void settings();              //FUNCTION TO CHANGE           {                                                                         {scale = 4;
THE SETTINGS(TIME AND                          VOLT-          line(a,0,a,may);                                                          break;
AGE)                                                          }                                                                         }
                                                              setcolor(BROWN);                                              case ‘3’ :
 long int samp=7000; //PLEASE CHECK THESE VAL-                setlinestyle(0,3,0);                                          {
UES WHEN CONVERSION IS                                        line(max/2,0,max/2,may);                                      outtextxy(10,340,”TYPE VALUES FROM 1 TO 9 (mini-
                     // NOT PROPER(+-3000)                    line(0,may/2,max,may/2);                                  mize) or m to (magnify)”);
                                                              setcolor(RED);                                                d=getch();
  float scale=1;                                              for(a=0,c=0;a<=max;a+=50,c++)                                 if(d==’m’)
  float times=1;                                              {                                                                {
  char again=’a’;                                             putpixel(a,may/2,BLUE);                                          outtextxy(10,360,”TYPE a (1 unit = 0.5 volt) or b (1
  int number=800;                                             itoa((a-c*30)*times/2,str,10);                            unit = 0.25 volt)”);
                                                              outtextxy(a+3,may/2+3,str);                                      switch(getch())
  void main()                                                 }                                                                         {
  {                                                           for(b=(may/2)-45,c=1;b>=0;b-=45,c++)                                        case ‘a’:
  int i,j,k,a[1700],b[1700],c[1700],e[1700]; //This value     {                                                                             {
1700 is given when we want to compress the waveform           itoa((c*scale),str,10);                                                        scale=0.5;
                                                              putpixel((max/2),b,BLUE);                                                      break;
               //done when we compress the time scale         outtextxy((max/2)+3,b+3,str);                                                 }
   long int b1;                                               }                                                                           case ‘b’:
   clrscr();                                                  for(b=(may/2)+45,c=1;b<=800;b+=45,c++)                                        {
   settings();                                                {                                                                              scale=0.25;
   while(again==’a’)                                          itoa((c*scale),str,10);                                                        break;
   {                                                          strcat(st,str);                                                               }
   for(i=0;i<number;i++)                                      putpixel((max/2),b,BLUE);                                                  }
   {                                                          outtextxy((max/2)+2,b+2,st);                                     }
   outportb(cont,0x05^0x0b);                                  strcpy(st,”-”);                                               else
   outportb(cont,0x04^0x0b);                                  }                                                             { e[0]=’0';
   e[i]=(inportb(stat)^0x80)&0x08;                            setcolor(MAGENTA);                                               e[1]= ‘0’;
   for(b1=0;b1<=samp;b1++)              //sampling time                                                                        e[2]=d;
is approximately 50 µsec                                      outtextxy(max-80,may/2+30,”time(msec)”);                      scale=atoi(e);
   {}                                                         settextstyle(0,1,0);                                          break;
                                                              outtextxy((max/2)-10,0,”volt(s)”);                            }
   outportb(cont,0x05^0x0b);                                                                                                }
   outportb(cont,0x01^0x0b);                                  setlinestyle(0,0,0);                                          }
   outportb(cont,0x05^0x0b);                                  setcolor(RED);                                               }
   while((inportb(cont)&0x08)==0x00) //converstion time       moveto(0,may/2);                                            setcolor(BROWN);
is approximately 100 µsec                                     for(b=0,c=0;b<=number;c+=1, b++)                            outtextxy(10,380,”TYPE C TO CHANGE TIME SET-
   {                                                          {                                                         TINGS”);
   }                                                          if(e1[b]!=0x08)                                             m=getch();
                                                              {                                                           if( m==’c’)
  outportb(data,0xf0);                                        lineto(c*times,((may/2)-a1[b]));                            {
  a[i]=(inportb(stat)^0x80)&0xf0;                             }                                                           cleardevice();
  outportb(data,0x01);                                        else                                                        outtextxy(10,20,”X AXIS 1 unit= 10msec CHANGE TO
  b[i]=(inportb(stat)^0x80)&0xf0;                             {                                                         x(10msec)”);
  outportb(data,0xff);                                        lineto(c*times,((may/2)+a1[b]));                            outtextxy(10,40,”TYPE ‘a’ IF x IS (2 to 9) ,’b’ IF x IS (10
  }                                                           }                                                         to 99) AND ‘c’ IF x IS (.5 TO .9)”);
  for(i=0;i<number;i++)                                       }                                                           switch(getch())
  {                                                           again = getch();                                                 {
  a[i]=a[i]>>4;                                               closegraph();                                                    case ‘a’:
  c[i]=a[i]+b[i];                                             restorecrtmode();                                                  outtextxy(10,60,”x value is ....”);
  c[i]=c[i]*0.0196*45/scale;                                                                                                     n[0]=getch();
  }                                                           }                                                                  times=atoi(n);
  graphics(c,e);                                                                                                                 itoa(times,n,10);
  }                                                           void settings()                                                    outtextxy(10,70,n);
                                                              {                                                                  break;
  }                                                           int gd=DETECT,gm,error,max,may,b;                                case ‘b’:
                                                              char c,d,e[2],m,*n;                                                outtextxy(10,60,”x value is ....”);
  void graphics(int a1[],int e1[])                            times=1;                                                           n[0]=getch();
  {                                                           initgraph(&gd,&gm,”c:\\tc\\bgi”);         //default bgi            n[1]=getch();
  int gd=DETECT,gm,max,may,a,b,c,im,error,get=5;            directory path                                                       times=atoi(n);
                                                              error=graphresult();                                               itoa(times,n,10);
  char str[10],*st=”-”,d;                                     if(error != grOk)                                                  outtextxy(10,70,n);
                                                              {                                                                  break;
  clrscr();                                                   printf(“Graphics error %s /n”,grapherrormsg(error));
  initgraph(&gd,&gm,”c:\\tc\\bgi”);                //use      printf(“PRESS ANY KEY TO EXIT”);                               case ‘c’:
default bgi path                                              getch();                                                                   outtextxy(10,60,”x value is...”);
  error=graphresult();                                        exit(1);                                                                   getch();
  if(error != grOk)                                           }                                                                          n[0]=getch();
  {                                                           max=getmaxx();                                                             times=atoi(n)*0.1;
  printf(“Graphics error %s /n”,grapherrormsg(error)); /      setbkcolor(LIGHTBLUE);                                                     outtextxy(10,70,”scale decremented”);
/reports error when                                           settextstyle(1,0,0);                                                       break;
                                                              setcolor(BROWN);
             //graphics is not set                            outtextxy(max/2-60,20,”SETTINGS”);                          }
  printf(“PRESS ANY KEY TO EXIT”);                            line(0,60,800,60);                                          number=800;
  getch();                                                    setcolor(MAGENTA);                                          if(times<1)
  exit(1);                                                    settextstyle(1,0,1);                                        {number=number/times;
  }                                                           outtextxy((max/4)-70,80,”Voltage Scale”);                   }
  setbkcolor(LIGHTCYAN);                                      settextstyle(0,0,0);                                        getch();
  setcolor(MAGENTA);                                          setcolor(BROWN);                                            }
                                                              outtextxy(10,120,”DEFAULT       :”);                        closegraph();
  settextstyle(0,0,2);                                        outtextxy(10,120,”         1 unit = 1 volt”);               restorecrtmode();
  max=getmaxx();                                              setcolor(RED);                                              }