DECLARE SUB coilgetvn (nh%, vm!(), vp!()) DECLARE SUB hp3457extsig (i%) DECLARE SUB hp3457cf (cf%, freq!) DECLARE SUB hp3457cnvtrig (c%, n%, v!()) DECLARE SUB coilcalcvn (ns%, v!(), vm!(), vp!()) DECLARE SUB coilfitvnmain (n%, ns%, y!(), a!, b!, c!, phi!, res!) DECLARE SUB coilgetf (f!) DECLARE SUB coilgetv (ns%, v!(), sv!()) DECLARE SUB coillogf (logfile$, freq!) DECLARE SUB coillogfitvnmain (logfile$, n%, a!, b!, c!, phi!, res!) DECLARE SUB coillogv (logfile$, rawptr%) DECLARE SUB coillogvn (logfile$, nmain%, vmmain!, vpmain!) DECLARE SUB coilrawv (logfile$, rawptr%, ns%, v!()) DECLARE SUB FFTCalc (xreal!(), yimag!(), numdat%) DECLARE FUNCTION FFTMagnitude! (xr(), yi(), n%, i%) DECLARE FUNCTION FFTPhase! (xr(), yi(), n%, i%) '**************************************************************************** 'Module COIL.BAS ' 'Zachary Wolf '1/4/95 '**************************************************************************** 'Open the parameter file REM $INCLUDE: 'param.inc' 'The required parameters are 'logfileP$ 'rawfileP$ 'coilnsampleP% 'coilfreqhpchanP% 'coilvolthpchanP% 'coilnrotaveP% ' 'The required parameters are in 'FILE 'COIL ' 'Sample COIL parameters 'COIL 'CONST coilfreqhpchanP% = 6 'HP3457 channel # for the coil frequency 'CONST coilnsampleP% = 64 'the number of voltage samples per revolution 'CONST coilnrotaveP% = 10 'the number of coil rotations for V average 'COMMON SHARED /coil/ coilradiusmP!, coilnturnsP%, coilvolthpchanP% SUB coilcalcvn (ns%, v!(), vm!(), vp!()) '**************************************************************************** 'This subroutine calculates the magnitude and phase of each voltage harmonic. ' 'Input: ' ns%, the number of encoder pulses per revolution ' v!(0 to ns%-1), the voltage samples for one coil revolution ' 'Output: ' vm!(0 to ns%/2), the magnitude of the voltage at each harmonic ' vp!(0 to ns%/2), the phase of the voltage at each harmonic in degrees -180 to 180 ' 'Zachary Wolf '7/9/94 '**************************************************************************** 'Initialize DIM xr!(0 TO ns% - 1) DIM yi!(0 TO ns% - 1) FOR i% = 0 TO ns% - 1 xr!(i%) = v!(i%) yi!(i%) = 0! NEXT i% 'Get the voltage at each harmonic using an FFT CALL FFTCalc(xr!(), yi!(), ns%) 'Calculate the magnitude and phase of each voltage harmonic FOR i% = 0 TO ns% / 2 vm!(i%) = FFTMagnitude(xr!(), yi!(), ns%, i%) vp!(i%) = FFTPhase(xr!(), yi!(), ns%, i%) NEXT i% 'Convert from radians to degrees 'Convert from (0,360) to (-180,180) FOR i% = 0 TO ns% / 2 vp!(i%) = vp!(i%) * 180! / 3.141592654# IF vp!(i%) > 180! THEN vp!(i%) = -(360! - vp!(i%)) NEXT i% END SUB SUB coilfitvnmain (n%, ns%, y!(), a!, b!, c!, phi!, res!) '**************************************************************************** 'This subroutine fits ns data points to a sine wave having n cycles in the 'ns points. 'The fit is to y = a!*sin(n*2pi*i/ns) + b!*cos(n*2pi*i/ns) ' = c!*cos(n*2pi*i/ns + phi!) 'The rms of the residuals is also returned. 'The conversion from a and b to c and phi goes as follows: 'y = c!*cos(n*2pi*i/ns - nphi!) 'nphi! = -phi! 'y = c!*cos(n*2pi*i/ns)*cos(nphi!) + c!*sin(n*2pi*i/ns)*sin(nphi!) 'a! = c!*sin(nphi!), b! = c!*cos(nphi!) 'c!^2 = a!^2 + b!^2, c! = sqr(a!^2 + b!^2) 'a!/b! = tan(nphi!), nphi! = atan(a!/b!), consider different quadrants ' 'Input: ' n%, the number of cycles in the fitted sine wave ' ns%, the number of data points ' y!(0 to ns%-1), the data points ' 'Output: ' a!, the coeffecient of the sin term from the fit ' b!, " cos " ' c!, the fitted amplitude ' phi!, the fitted phase in degrees ' res!, the rms of the residuals ' 'Zachary Wolf '8/19/94, 5/4/95 '**************************************************************************** 'Parameters pi! = 3.1415926# 'Compute various sums Sss! = 0! Scc! = 0! Ssc! = 0! Sys! = 0! Syc! = 0! FOR i% = 0 TO ns% - 1 Sss! = Sss! + SIN(n% * 2 * pi! * i% / ns%) * SIN(n% * 2 * pi! * i% / ns%) Scc! = Scc! + COS(n% * 2 * pi! * i% / ns%) * COS(n% * 2 * pi! * i% / ns%) Ssc! = Ssc! + SIN(n% * 2 * pi! * i% / ns%) * COS(n% * 2 * pi! * i% / ns%) Sys! = Sys! + y!(i%) * SIN(n% * 2 * pi! * i% / ns%) Syc! = Syc! + y!(i%) * COS(n% * 2 * pi! * i% / ns%) NEXT i% 'Compute the determinant d! = Sss! * Scc! - Ssc! * Ssc! 'Compute the sin and cos coefficients a! = (Sys! * Scc! - Ssc! * Syc!) / d! b! = (Sss! * Syc! - Sys! * Ssc!) / d! 'Compute the amplitude coefficient c! = SQR(a! ^ 2 + b! ^ 2) 'Compute the phase coefficient, nphi! = -phi! IF a! > 0 AND b! > 0 THEN nphi! = ATN(a! / b!) IF a! > 0 AND b! < 0 THEN nphi! = pi! - ATN(-a! / b!) IF a! < 0 AND b! > 0 THEN nphi! = -ATN(-a! / b!) IF a! < 0 AND b! < 0 THEN nphi! = -pi! + ATN(a! / b!) IF a! = 0 AND b! >= 0 THEN nphi! = 0! IF a! = 0 AND b! < 0 THEN nphi! = pi! IF b! = 0 AND a! > 0 THEN nphi! = pi! / 2 IF b! = 0 AND a! < 0 THEN nphi! = -pi! / 2 phi! = -nphi! phi! = phi! * 180! / pi! 'convert to degrees 'Compute the rms of the residuals res! = 0! FOR i% = 0 TO ns% - 1 res! = res! + (y!(i%) - a! * SIN(n% * 2 * pi! * i% / ns%) - b! * COS(n% * 2 * pi! * i% / ns%)) ^ 2 NEXT i% res! = SQR(res! / ns%) 'Log the results CALL coillogfitvnmain(logfileP$, n%, a!, b!, c!, phi!, res!) END SUB SUB coilgetf (f!) '**************************************************************************** 'This subroutine is used to get the rotation frequency of a measurement coil. ' 'Output: ' f!, the average of the frequency measurements ' 'Zachary Wolf '10/6/94, 11/15/94 '**************************************************************************** 'Simplify the notation ns% = coilnsampleP% '# encoder pulses per revolution cf% = coilfreqhpchanP% 'HP3457 channel for the coil frequency 'Make sure there are trigger pulses for the frequency measurement CALL hp3457extsig(0) 'Perform the frequency measurement CALL hp3457cf(cf%, f!) 'Take out ns% pulses per revolution f! = f! / ns% 'Log the coil rotation frequency CALL coillogf(logfileP$, f!) END SUB SUB coilgetv (ns%, v!(), sv!()) '**************************************************************************** 'This subroutine gets the triggered voltages from the coil. ' 'Input: ' ns%, the number of voltage samples per revolution ' 'Output: ' v!(0 to ns%-1), the average voltage at each sample point ' sv!(0 to ns%-1), the standard deviation of v at each sample point ' 'Zachary Wolf '8/14/94, 11/15/94 '**************************************************************************** 'Simplify the notation c% = coilvolthpchanP% nr% = coilnrotaveP% 'Initialize data arrays DIM vnr!(0 TO nr% * ns% - 1) 'voltage samples DIM v2d!(0 TO ns% - 1, 1 TO nr%) 'put samples in 2d array 'Make the measurement over nr% rotations CALL hp3457cnvtrig(c%, nr% * ns%, vnr!()) 'Put the samples in a 2d array for ease of handling FOR i% = 0 TO ns% - 1 FOR j% = 1 TO nr% v2d!(i%, j%) = vnr!(i% + (j% - 1) * ns%) NEXT j% NEXT i% 'Compute the average at each sample point FOR i% = 0 TO ns% - 1 v!(i%) = 0! FOR j% = 1 TO nr% v!(i%) = v!(i%) + v2d!(i%, j%) NEXT j% v!(i%) = v!(i%) / nr% NEXT i% 'Compute the standard deviation of the voltage at each sample point FOR i% = 0 TO ns% - 1 sv!(i%) = 0! FOR j% = 1 TO nr% sv!(i%) = sv!(i%) + (v2d!(i%, j%) - v!(i%)) ^ 2 NEXT j% sv!(i%) = SQR(sv!(i%) / nr%) NEXT i% 'Log that a measurement was made CALL coillogv(logfileP$, rawptr%) 'Save the samples in the raw data file CALL coilrawv(rawfileP$, rawptr%, ns%, v!()) END SUB SUB coilgetvn (nh%, vm!(), vp!()) '**************************************************************************** 'This subroutine performs one coil voltage measurement and returns the 'voltage harmonics. ' 'Input: ' nh%, the number of harmonics to record ' 'Output: ' vm!(1 to nh%), voltage magnitude at each harmonic ' vp!(1 to nh%), voltage phase in degrees at each harmonic ' 'Zachary Wolf '11/15/94, 1/1/95, 5/4/95 '**************************************************************************** 'Simplify the notation ns% = coilnsampleP% 'Initialize data arrays DIM v!(0 TO ns% - 1) 'voltage samples DIM sv!(0 TO ns% - 1) 'standard deviation of v at each sample point DIM vmfft!(0 TO ns% / 2) 'voltage magnitude at each harmonic DIM vpfft!(0 TO ns% / 2) 'voltage phase at each harmonic 'Sample the voltage from the coil CALL coilgetv(ns%, v!(), sv!()) 'Calculate the harmonics in the voltage sample CALL coilcalcvn(ns%, v!(), vmfft!(), vpfft!()) 'Return the requested values FOR i% = 1 TO nh% vm!(i%) = vmfft!(i%) vp!(i%) = vpfft!(i%) NEXT i% 'For the log file, find the maximum vm nmain% = 1 FOR i% = 1 TO nh% IF vm!(i%) > vm!(nmain%) THEN nmain% = i% NEXT i% 'Log the maximum harmonic CALL coillogvn(logfileP$, nmain%, vm!(nmain%), vp!(nmain%)) 'Fit a sin wave to v! and record the fit in the log file CALL coilfitvnmain(nmain%, ns%, v!(), a!, b!, c!, phi!, res!) 'Message 'PRINT "Coil Voltage V(" + LTRIM$(STR$(nmain%)) + ") = "; vm!(nmain%); " V" END SUB SUB coillogf (logfile$, freq!) '**************************************************************************** 'This subroutine writes the coil rotation frequency to the log file. ' 'Input: ' logfile$, the name of the log file ' freq!, the measured coil rotation frequency ' 'Zachary Wolf '10/3/94 '**************************************************************************** 'Open the log file filenum% = FREEFILE OPEN logfile$ FOR APPEND AS filenum% 'Print the results PRINT #filenum%, PRINT #filenum%, TIME$; " Coil Rotation Frequency, Fcoil = "; freq!; " Hz" 'Close the log file CLOSE filenum% END SUB SUB coillogfitvnmain (logfile$, n%, a!, b!, c!, phi!, res!) '**************************************************************************** 'This subroutine logs the parameters of the fit to the voltage samples. ' 'Input: ' logfile$, the name of the log file ' n%, the number of cycles in the fitted sine wave ' a!, the coeffecient of the sin term from the fit ' b!, " cos " ' c!, the fitted amplitude ' phi!, the fitted phase in degrees ' res!, the rms of the residuals ' 'Zachary Wolf '1/5/95, 5/4/95 '**************************************************************************** 'Open the log file filenum% = FREEFILE OPEN logfile$ FOR APPEND AS filenum% 'Write the fit parameters PRINT #filenum%, PRINT #filenum%, TIME$; " Coil Voltage Fit: " PRINT #filenum%, "Vfit(i) = "; PRINT #filenum%, USING "##.#######"; c!; PRINT #filenum%, USING " V * cos(#*2pi*i/ns + "; n%; PRINT #filenum%, USING "####.##"; phi!; PRINT #filenum%, " deg)" PRINT #filenum%, " = "; PRINT #filenum%, USING "##.#######"; a!; PRINT #filenum%, USING " V * sin(#*2pi*i/ns) + "; n%; PRINT #filenum%, USING "##.#######"; b!; PRINT #filenum%, USING " V * cos(#*2pi*i/ns)"; n% PRINT #filenum%, "RMS of the residuals = "; PRINT #filenum%, USING "##.####### V"; res! 'Close the log file CLOSE filenum% END SUB SUB coillogv (logfile$, rawptr%) '**************************************************************************** 'This subroutine writes to the log file that a coil voltage measurement 'was made. ' 'Input: ' logfile$, the name of the log file ' 'Output: ' rawptr%, relates the line in the raw data file to the log file ' 'Zachary Wolf '1/5/95 '**************************************************************************** 'Relate log file to raw data file STATIC index% index% = index% + 1 rawptr% = index% 'Open the log file filenum% = FREEFILE OPEN logfile$ FOR APPEND AS filenum% 'Print the results PRINT #filenum%, PRINT #filenum%, TIME$; " Coil Voltage Measurement # "; rawptr%; " Made, Stored in RAWFILE" 'Close the log file CLOSE filenum% END SUB SUB coillogvn (logfile$, nmain%, vmmain!, vpmain!) '**************************************************************************** 'This subroutine writes information about the main harmonic to the log file. ' 'Input: ' logfile$, the name of the log file ' nmain%, the number of the main harmonic ' vmmain!, the magnitude of the main harmonic ' vpmain!, the phase of the main harmonic ' 'Zachary Wolf '5/4/95 '**************************************************************************** 'Open the log file filenum% = FREEFILE OPEN logfile$ FOR APPEND AS filenum% 'Print the results PRINT #filenum%, PRINT #filenum%, TIME$; " Coil Voltage Main Harmonic From FFT:" PRINT #filenum%, "Nmain = "; nmain%; ", Vm main = "; vmmain!; " V, Vp main = "; vpmain!; " deg" 'Close the log file CLOSE filenum% END SUB SUB coilplotf '**************************************************************************** 'This subroutine gets coil rotation frequency samples and puts them in 'a file for plotting. ' 'Zachary Wolf '5/4/95 '**************************************************************************** 'Initialize a log file logfileP$ = "fcoillog.dat" filenum% = FREEFILE OPEN logfileP$ FOR OUTPUT AS filenum% CLOSE filenum% 'Message PRINT PRINT "Beginning the coil rotation frequency measurement cycle..." 'Get the measurement time PRINT INPUT "How long do you wish to record the coil rotation frequency? (min) ", tmin! tsec! = tmin! * 60 'Calculate the number of measurements which will be made tbtwnmeassec% = 5 nmeas% = 1 + tsec! / tbtwnmeassec% 'Initialize the data arrays DIM t!(1 TO nmeas%) DIM f!(1 TO nmeas%) 'Record the starting time t0! = TIMER 'Record the frequency at regular intervals up to tsec FOR i% = 1 TO nmeas% 'Record the time of the measurement tm! = TIMER t!(i%) = tm! - t0! 'Measure the frequency CALL coilgetf(f!(i%)) 'Write the measurements to the screen PRINT PRINT "Time: "; TIME$; ", Fcoil = "; f!(i%); " Hz" 'Wait between measurements WHILE TIMER - tm! < tbtwnmeassec% WEND 'End of measurement loop NEXT i% 'Initialize a plot file filenum% = FREEFILE OPEN "fcoilplt.dat" FOR OUTPUT AS filenum% 'Write the samples to the plot file FOR i% = 1 TO nmeas% PRINT #filenum%, USING "######.##"; t!(i%); PRINT #filenum%, USING " ###.######"; f!(i%) NEXT i% 'Close the log file CLOSE filenum% END SUB SUB coilplotv '**************************************************************************** 'This subroutine gets voltage samples from the coil and puts them in 'a file for plotting. ' 'Zachary Wolf '5/4/95 '**************************************************************************** 'Initialize a log file logfileP$ = "vcoillog.dat" filenum% = FREEFILE OPEN logfileP$ FOR OUTPUT AS filenum% CLOSE filenum% 'Initialize a raw data file rawfileP$ = "vcoilraw.dat" filenum% = FREEFILE OPEN rawfileP$ FOR OUTPUT AS filenum% CLOSE filenum% 'Simplify the notation ns% = coilnsampleP% 'Initialize data arrays DIM v!(0 TO ns% - 1) 'voltage samples DIM sv!(0 TO ns% - 1) 'voltage samples 'Sample the coil voltage CALL coilgetv(ns%, v!(), sv!()) 'Initialize a plot file filenum% = FREEFILE OPEN "vcoilplt.dat" FOR OUTPUT AS filenum% 'Write the samples to the plot file FOR k% = 0 TO ns% - 1 PRINT #filenum%, USING "###"; k%; PRINT #filenum%, USING " ###.######"; v!(k%); PRINT #filenum%, USING " ###.######"; sv!(k%) NEXT k% 'Close the log file CLOSE filenum% END SUB SUB coilprintvn '**************************************************************************** 'This subroutine gets voltage samples from the coil, finds the harmonics, 'and puts them in a file for printing. ' 'Zachary Wolf '5/4/95 '**************************************************************************** 'Initialize a log file logfileP$ = "vnlog.dat" filenum% = FREEFILE OPEN logfileP$ FOR OUTPUT AS filenum% CLOSE filenum% 'Initialize a raw data file rawfileP$ = "vnraw.dat" filenum% = FREEFILE OPEN rawfileP$ FOR OUTPUT AS filenum% CLOSE filenum% 'Print the first 16 harmonics nh% = 16 'Initialize data arrays DIM vm!(1 TO nh%) 'voltage magnitudes DIM vp!(1 TO nh%) 'voltage phases 'Sample the coil voltage CALL coilgetvn(nh%, vm!(), vp!()) 'Initialize a print file filenum% = FREEFILE OPEN "vnprt.dat" FOR OUTPUT AS filenum% 'Write the samples to the print file PRINT #filenum%, "i, Vm(i), Vp(i)" FOR k% = 1 TO nh% PRINT #filenum%, USING "###"; k%; PRINT #filenum%, USING " ##.#####"; vm!(k%); PRINT #filenum%, USING " ####.##"; vp!(k%) NEXT k% 'Close the log file CLOSE filenum% END SUB SUB coilrawv (logfile$, rawptr%, ns%, v!()) '**************************************************************************** 'This subroutine writes voltage samples to the log file. ' 'Inputs: ' logfile$, the name of the log file ' rawptr%, relates raw data file to log file ' ns%, the number of voltage samples ' v!(0 to ns%-1), the voltage samples ' 'Zachary Wolf '1/7/95 '**************************************************************************** 'Open the log file filenum% = FREEFILE OPEN logfile$ FOR APPEND AS filenum% 'Write the samples to the log file PRINT #filenum%, USING "###"; rawptr%; FOR i% = 0 TO ns% - 1 PRINT #filenum%, USING " ###.####"; v!(i%); NEXT i% PRINT #filenum%, 'Close the log file CLOSE filenum% END SUB