/*-----------------------------------------------
Aj-psi.cpp
This program is used to adjust the phase lag, i.e, psi
of the vertical vibratioin while the other parameters
i.e., frequency, vibration angle and vertical vibration
amplitude remain unchanged.
------------------------------------------------*/
#define pi 3.1415926
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#include <math.h>
#include <complex.h>
/*------------- Time Delay Subprogram ---------------*/
void udelay(int num)
{
int x,y;
for(x=0;x<=10;x++)
for(y=0;y<num;y++);
}
/*----------- Time Delay Subprogram End -------------*/
/*------------- D-A Conversion Subprogram ------------*/
/*---------------------------------------------
syntax: setAnalog0(intAddress,intData) &
setAnalog1(intAddress,intData)
where: setAnalog0(intAddress,intData) for DA Channel0
setAnalog1(intAddress,intData) for DA Channel1
intAddress=The base address of the Super 14 ADDA Card
intData=The data to be send out
0=minimum voltage
0X3fff=maximum voltage
return: void
-----------------------------------------------*/
void setAnalog0(int intAddress,int intData)
{
int lb,hb;
lb=intData&0xff;
hb=(intData&0x3f00)>>8;
outportb(intAddress+5,hb);
outportb(intAddress+4,lb);
}
void setAnalog1(int intAddress,int intData)
{
int lb,hb;
lb = intData &0xff;
hb = (intData &0x3f00)>>8;
outportb(intAddress+7,hb);
outportb(intAddress+6,lb);
}
/*----------- D-A Conversion Subprogram End ----------*/
//int data0[100],data1[100];
int adata0[100],adata1[100];
float ds0[100],ds1[100];
float vm0[100],vm1[100];
int theAddress,theChannel;
int base825,i,a,j,dh,dl,k,d0,d1,ns,np,jj;
float f,ah,av,phs,vb0,vb1,s0,s1;
float kp0,ki0,kd0,e0,ep0,es0,u0,up0,ts;
float kp1,ki1,kd1,e1,ep1,es1,u1,up1;
float fp0,fp1,psi,anog,gama;
char ans;
static int fph0[36]={-50,-52,-54,-59,-74,-62,-58,-57,-56,-59,-59,-60,-60,-56,-56,-59,-208,-188,-237,-213,-229,-238,-242,-242,-245,-252,-254,-255,-258,-256,-256,-257,-214,-257,-258,-245};
static int fph1[36]={-56,-56,-57,-63,-79,-66,-61,-61,-61,-62,-63,-62,-63,-65,-66,-68,-69,-73,-75,-107,-185,-205,-203,-189,-186,-208,-216,-224,-230,-235,-241,-244,-246,-249,-250,-252};
/******************* MAIN PROGRAM *******************/
void main()
{
clrscr();
gotoxy(10,10);
puts("PC-7429(AD),Super ADDA14(DA) and 8255-53(Timer&DI/O) Used");
gotoxy(10,12);
puts("TWO AD channels of PC-7429: Ch0&Ch1 for sampling");
gotoxy(10,14);
puts("TWO DA channels of Super ADDA14: Ch0&Ch1 for analog output");
gotoxy(10,16);
puts("8253 COUNTER 0 Mode 0, timing for sampling period");
gotoxy(10,18);
puts("8253 COUNTER 1 and 2 not used");
gotoxy(10,20);
puts("8255-1 Port-A Basic input mode 0x9b");
gotoxy(10,22);
puts("8255-2 Not used");
puts(" ");
theAddress=0x270; //base address of SupperADDA14
base825=0x300; //base address of 8255-53 I/O
/*
printf("Please input frequency f=");
scanf("%f",&f);
printf("Please input phase lag phs=");
scanf("%f",&phs);
printf("Please input vertical amplitude av=");
scanf("%f",&av);
printf("Please input horizontal amplitude ah=");
scanf("%f",&ah);
printf("Please input no. of sampling poits (<=100), ns=");
scanf("%d",&ns);
printf("Please input no. of periods for average amplitude, np=");
scanf("%d",&np);
printf("Please input PID parameter, kp0=");
scanf("%f",&kp0);
printf("Please input PID parameter, kp1=");
scanf("%f",&kp1);
printf("Please input PID parameter, ki0=");
scanf("%f",&ki0);
printf("Please input PID parameter, ki1=");
scanf("%f",&ki1);
printf("Please input PID parameter, kd0=");
scanf("%f",&kd0);
printf("Please input PID parameter, kd1=");
scanf("%f",&kd1);
*/
ns=100; np=50;
kp0=0.04; kp1=0.08; ki0=0.04; ki1=0.08; kd0=0.01; kd1=0.01;
gama=0-40+180;
f=53; psi=25; gama=gama+240; anog=1.2;
do
{
av=anog*9.8*10000/(2*pi*f*2*pi*f);
ah=av/tan(psi*pi/180.0);
printf("/n");
printf("av=%fV, ah=%fV/n",av,ah);
printf("f=%f, psi=%f, gama=%f, anog=%f/n",f,psi,gama,anog);
printf("/n");
if(f<48.0||psi<20.0)
{kp0=0.01; kp1=0.02; ki0=0.008; ki1=0.04; kd0=0.03; kd1=0.01;}
if(f>59.0)
{kp0=0.01; kp1=0.04; ki0=0.04; ki1=0.04; kd0=0; kd1=0;}
/*---------- Calculate desired output signals-------*/
ts=1/(f*ns);
i=f-35;
fp0=fph0[i]*pi/180.0;
fp1=fph1[i]*pi/180.0;
phs=gama*pi/180.0;
if(f==53.0)
{fp0=-238*pi/180.0;
fp1=-73*pi/180.0;}
for(i=0;i<ns;i++)
{
// data0[i]=ah*sin(2.0*pi/ns*(float)i)/5.0*8191.0+8192.0;
// data1[i]=av*sin(2.0*pi/ns*(float)i+phs)/5.0*8191.0+8192.0;
ds0[i]=sin(2.0*pi/ns*(float)i-fp0)/5.0*8191.0;
ds1[i]=sin(2.0*pi/ns*(float)i-fp1+phs)/5.0*8191.0;
}
/*-------- Calculate desired output signals End-----*/
/*------------- 8255 and 8253 mode setting ----------*/
a=4750000/(f*ns); //timing constant
dl=a&0xff; //low 4 bits
dh=(a&0xff00)>>8; //high 4 bits
outportb(base825+3,0x9b); //8255 control mode0 reading
outportb(base825+11,0x30); //8253 control timer0 mode0
/*----------- 8255 and 8253 mode setting End --------*/
/*------------ initialize PC-7429 -------------*/
// sample program for :
// speed = 500KHZ
// block channel scan mode
// sampleing 2 channels, start channel=0, stop channel=1
// irq disable
// data length 1 points / channel
// using software start
// using inner clk-source
// base adress: 0x210
// set mode
// soft-trgiger to start , bit 0 = 0
// clk , inner clk, bit 1 = 0
// irq disable , bit 2 = 0
// stop channel is : 1, bit 4 - 7 = 0x1
outp(0x213,0x10);
// set start channel = 0
outp(0x212,0);
// set timer, F=500KHZ, data to timer is 2uS / 0.2 uS = 10
outp(0x21f,0xb4); // initial timer mode
outp(0x21e,10); // timer low 8bit
outp(0x21e,0); // high 8bit
// set length counter, length = 2x1 = 2
outp(0x21f,0x32); // initial counter mode
k=2; // length
j=k/256; // high 8bit
i=k-j*256; // low 8bit
outp(0x21c,i); // latch low 8bit
outp(0x21c,j); // latch high 8bit
/*----------initialize PC-7429 over-------------*/
/*---------------Sending Analog Signals Loop------------*/
i=0; jj=0; s0=0; s1=0;
e0=0; e1=0; es0=0; es1=0; ep0=0; ep1=0;up0=0;up1=0;
outportb(base825+8,dl);
outportb(base825+8,dh); //timing for sampling period starts
do{
/*--------------A to D Conversion---------------*/
outp(0x216,0); // rewind the adress counter & system reset
// udelay(100);
outp(0x215,0); // start A-D conversion
do{
j=inp(0x212) & 1;
}while(j!=0); // if D0 = 0 , A-D conversion finished
outp(0x216,0); // rewind the adress counter & system reset
// udelay(100);
d0=inpw(0x210); //read A-D channel0 convertion data
d1=inpw(0x210); //read A-D channel1 convertion data
vb0=(d0-2048)*5.0/2048-0.05;
vb1=(d1-2048)*5.0/2048-0.02; //0.1V is used for sensor offset
if(vb0>3.9)
{printf("vb0>3.9V/n");
break;}
if(vb1>3.0)
{printf("vb1>3.0V/n");
break;}
/*--------------A to D Conversion End------------*/
u0=kp0*e0+ki0*es0+kd0*(e0-ep0);
u1=kp1*e1+ki1*es1+kd1*(e1-ep1);
ep0=e0; ep1=e1;
if(u0>=3.0) u0=3.0;
if(u0<=-3.0) u0=-3.0;
if(u1>=2.0) u1=2.0;
if(u1<=-2.0) u1=-2.0;
if(e0==0) u0=up0;
if(e1==0) u1=up1;
adata0[i]=u0*ds0[i]+8192;
adata1[i]=u1*ds1[i]+8192;
setAnalog0(theAddress, adata0[i]);
setAnalog1(theAddress, adata1[i]);
up0=u0; up1=u1;
// udelay(70); //suit D-A output voltage settling
/*-----------To get the Amplitude of a Period-----*/
if(i==0)
{
vm0[jj]=vb0;
vm1[jj]=vb1;
}
else
{
if(vb0>=vm0[jj]) vm0[jj]=vb0;
if(vb1>=vm1[jj]) vm1[jj]=vb1;
}
/*---------To get the Amplitude of a Period End-----*/
i=i+1;
if(i>=ns)
{
i=0; //ns--no. of sampling points in one cycle
s0=s0+vm0[jj];
s1=s1+vm1[jj];
jj=jj+1;
}
if(jj>=np)
{
s0=s0/np; s1=s1/np;
e0=ah-s0; e1=av-s1;
s0=0; s1=0;
jj=0;
if(e0>ah) e0=ah;
if(e1>av) e1=av;
if(fabs(e0)<=0.020) e0=0;
if(fabs(e1)<=0.015) e1=0;
es0=es0+e0;
es1=es1+e1;
}
/*------------- Sampling period timing UP? ----------*/
a=inportb(base825+0);
a=a&0x01;
if(a==1)
{
printf("Time setting is not enough");
break;
}
else
{
do{
a=inportb(base825+0);
a=a&0x01;
}while(a!=1);
}
/*----------- Sampling period timing UP!! ----------*/
outportb(base825+8,dl); //reset timer
outportb(base825+8,dh);
a=inportb(base825+0); //check PA1 for user stop
a=a&0x02;
if(a==2) break; //if PA1=1,stop loop
}while(1<10);
/*-------------Sending Analog Signals Loop End----------*/
printf("program stopped by immergency button/n");
setAnalog0(theAddress, 8192);
setAnalog1(theAddress, 8192);
printf("Repeat,Next,Stop? Please key in R,N,or S/n");
do
{
ans=toupper(getch());
if(ans=='R') break;
if(ans=='N')
{psi=psi+2.5;
break;}
if(ans=='S') exit(0);
}while(1<10);
if(psi>80.0) exit(0);
delay(500);
}while(1<10);
}
/***************** MAIN PROGRAM End *****************/