' ************************************************ ' ** Name: CLTRMS2K.BAS ** ' ** Type: Program ** ' ** Module: Main Module ** ' ** Language: Microsoft QuickBASIC 4.00 ** ' ** Programmer: A. Eliason 01-11-94 ** ' ************************************************ ' ' Y2K Search for Year 2000 problems begun 7-14-1998 AHE ' Y2K Problems fixed 10-10-1998 AHE ' ' Main program for logging and processing Coulter data on USGS ' Sed Lab system. ' ' USAGE: No command line parameters ' .MAK FILE: (none) ' PARAMETERS: (none) ' ARRAYS: ' ' ' VARIABLES: ' A$ temporary string input ' QLabNo$ full lab # ' QTubeDia$ tube diameter ' QSampID$ sample i.d. ' QProjID$ project i.d. ' QCruiseID$ cruise i.d. ' QReqBy$ requested by ' QOperID$ operator i.d. ' Y2K new format: ' QDate$ full date @ mmddyyyy 'old QDate$ full date @ mm/dd/yy ' QTime$ full time @ hh:mm:ss ' QSampWeight$ sample weight RSA only ' QCoarseWeight$ coarse weight " " ' QSandWeight$ sand weight " " ' ' ' DECLARATIONS: ' none ' ************************************************************ ' ** Name: CLTRMS2K.BAS ** ' ** Type: MAIN [ X ] FUNCTION [ ] SUB [ ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: Version # in main module includes date ** ' ** as: MMDDYY ** ' ** Library: Standard *.LIB, *.QLB ** ' ** Description: Please see comments within this routine ** ' ** ** ' ** Usage: If no info here please see the line ** ' ** comments. ** ' ************************************************************ ' Main program for logging and testing Multisizer II data on USGS ' Sed Lab system. ' ' USAGE: No command line parameters ' .MAK FILE: (none) ' PARAMETERS: (none) ' ' ' VARIABLES: as described within program ' CONSTANTS: CONST FALSE = 0 CONST TRUE = NOT FALSE CONST PI = 3.1415927# CONST BLACK = 0, WHITE = 15, BLINK = 16 ' DECLARATIONS DECLARE SUB AnyKey (Kee$) ' Wait for keypress DECLARE SUB ReadRawData (a$) ' Read raw MS data file DECLARE SUB GrabRawData (PortNo%) ' Get raw MS data from MS-II DECLARE SUB HeaderInfo () ' Convert raw data to HeaderData DECLARE SUB HeaderLables () ' Reads in a list of lables DECLARE SUB MakeTaData (AperDia) ' Converts to Ta Data format DECLARE SUB SizeCalc (Kc, NumChan, AppCurr, AppGain) ' Build size array MS2Sizes() DECLARE SUB DiffVolume (TotalCount, TotalVolume#) ' Calculate Differential Vol % DECLARE SUB ScreenPaint () ' Paint screen background DECLARE FUNCTION Volume (Dia) ' Calculate Volume from Diameter DECLARE FUNCTION NthRoot (n, v) ' Returns n th root of v ' ARRAYS: DIM RawData(0 TO 500) ' Entire data record from MS-II DIM DifVol(0 TO 256) ' Differential Vol %'s DIM HeaderLable$(0 TO 50) ' Text for displays & printouts DIM HeaderData$(0 TO 50) ' Converted header info as text DIM MS2Sizes(0 TO 256) ' Sizes of MS2 chan RIGHT edges DIM TaSizes(40) ' Table of Ta standard diameters DIM TaCounts(16) ' Converted MS2 to Ta Chan Counts DIM TaVolPct(16) ' Computed Ta Volume Percentages ' VERSION/Number MMDDYY Version$ = "101098 Y2K" ' Changed default com port from 2 to 1 AHE 9/4/97 ' Changed default com port from 1 to 2 AHE 10/10/98 ' Y2K revisions made 10/10/98 ' Begin code from CLTRQB93.BAS ' CONTSTANTS: 'FALSE = 0 'TRUE = NOT FALSE ESC$ = CHR$(27) FormFeed$ = CHR$(12) DiagMode% = FALSE ' Set to TRUE for diagnostic Displays PrintOn% = TRUE ' Set to TRUE for Printed output to LPT1 WIDTH LPRINT 255 ID$ = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_" ln1$ = "PLEASE ": ln2$ = "ENTER" TD = 200 DIM TIME(13), W$(7), Mo$(12), Mo(12) DIM Dia(38), VP(16), PC(16) DIM DD(2, 16): REM DISK DATA ARRAY DIM QMD$(16), QVP$(16) DATA "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday" DATA "Saturday" DATA "January","February","March","April" DATA "May","June","July","August","September","October","November" DATA "December" DATA .198,.250,.315,.397,.500,.630,.794,1.00,1.26,1.59,2.00,2.52 DATA 3.17,4.0,5.04,6.35,8.00,10.08,12.7,16.0,20.2,25.4,32.0,40.3 DATA 50.8,64.0,80.6,101.6,128,161,203,256,322,406,512,645,812,1024 DATA 31,28,31,30,31,30,31,31,30,31,30,31 ScreenPaint LOCATE 8, 21 PRINT " USGS - SEDIMENT LAB - WOODS HOLE - MA " SLEEP 3 FOR i = 0 TO 6 READ W$(i) NEXT i FOR i = 1 TO 12 READ Mo$(i) NEXT i FOR i = 1 TO 38 READ Dia(i) TaSizes(i) = Dia(i) NEXT i FOR i = 1 TO 12 READ Mo(i) NEXT i GOSUB ReadClock ' *********************************************************************** ' * * ' * MAIN PROGRAM BEGINS * ' * * ' *********************************************************************** CLS ' Clear Screen SCREEN 0 COLOR BLACK, WHITE CLS PRINT SPC(10); CHR$(201); STRING$(58, 205); CHR$(187) PRINT SPC(10); CHR$(186); SPC(58); CHR$(186) a$ = "COULTER(r) Multisizer II - Raw Data Acquisition Program" PRINT SPC(10); CHR$(186); SPC((58 - LEN(a$)) / 2); a$; SPC((58 - LEN(a$)) / 2); CHR$(186) PRINT SPC(10); CHR$(186); SPC(58); CHR$(186) PRINT SPC(10); CHR$(200); STRING$(58, 205); CHR$(188) PRINT : PRINT : PRINT PRINT " This program converts 256 Channel Multisizer II data to 12 or 14" PRINT " Channel data, as apropriate, in the same size ranges, channel" PRINT " allocations and formats as the obsolete Model TA II Coulter Counter." PRINT PRINT " This program may crash unless executed from within its own" PRINT " subdirectory and that subdirectory contains the files:" PRINT " 1. MS_LABEL.DAT an ASCII header lable text file" PRINT " 2. MSII.DAT a raw data file captured by a program such" PRINT " as PROCOMM or created by this program." PRINT " In order to capture data from the MS-II this program expects" PRINT " serial input at the COM1 or COM2 port at 9600 baud, NO parity," PRINT " 8 data bits, 1 stop bit." PRINT PRINT " 'COULTER' and 'Multisizer II' are registered trademarks of " PRINT " Coulter Electronics Limited, Northwell Drive, Luton Beds, LU3 3RH England" AnyKey (Kee$) CLS PRINT PRINT " This program was developed under U.S. Government contract, for " PRINT " US Geological Survey, Woods Hole, MA" PRINT PRINT " By:" PRINT PRINT " Eliason Data Services" PRINT " 230 Meetinghouse Road" PRINT " Mashpee, MA 02649 Tel: (508) 477-1400" PRINT PRINT " Eliason Data Services prohibits commercial use of this software and" PRINT " disclaims any liability for damages resulting from its use." PRINT AnyKey (Kee$) CLS PRINT PRINT PRINT "1. Read data from Multisizer II via COM port 1" PRINT "2. Read data from Multisizer II via COM port 2" PRINT "3. Read data from file MSII.DAT" PRINT PRINT "Please enter 1,2,3 [Default = 2]" PRINT "Just strike ENTER for normal operation" DO a$ = INKEY$ LOOP WHILE a$ = "" PortNo% = VAL(a$) IF PortNo% < 1 OR PortNo% > 3 THEN PortNo% = 2 PRINT PRINT INPUT "Do you want diagnostic listings? [Default = No] "; a$ IF UCASE$(LEFT$(a$, 1)) = "Y" THEN DiagMode% = TRUE PRINT INPUT "Do you want printed output? [Default = Yes] "; a$ IF UCASE$(LEFT$(a$, 1)) = "N" THEN PrintOn% = FALSE ' ************** INTRODUCTION ************** CLS PRINT " ********************* CLTRMS2K ************************" PRINT " Coulter MultiSizer II Data Logging Program " PRINT " Version # "; Version$ PRINT " Eliason Data Services (508) 477-1400 " PRINT PRINT "Please answer query questions with 'Y' for Yes, 'N' for No, or the information asked for. You may also just hit the 'RETURN' key to accept the default reply which is contained within square brackets, i.e. [ BLA ]." PRINT PRINT "Please set printer to proper 'Top Of Form' then turn it ON." PRINT "Set the Coulter Multisizer II for normal operation." INPUT "When done, please hit 'RETURN' "; a$ StartSamp: ' ************* START THE SAMPLE SEQUENCE *********** Ver = 0 SID$ = "PLEASE ENTER" IGF = -1 GOSUB ReadClock ' READ CLOCK PRINT PRINT "Enter 'Q' to Quit" Verify: PRINT PRINT "Operator Name: ["; OPN$; INPUT "] ", a$ IF a$ = "Q" OR a$ = "q" THEN SYSTEM IF a$ <> "" THEN OPN$ = a$ PRINT " Hello, "; OPN$; ". Nice to see you today." END IF PRINT PRINT "Requested by: ["; SN$; INPUT "] ", a$ IF a$ <> "" THEN SN$ = a$ END IF PRINT PRINT "Cruise I.D.: ["; CID$; INPUT "] ", a$ IF a$ <> "" THEN CID$ = a$ END IF PRINT PRINT "Project I.D.: ["; PID$; INPUT "] ", a$ IF a$ <> "" THEN PID$ = a$ END IF SID: PRINT : PRINT "Sample I.D.: ["; SID$; : INPUT "] ", a$ IF a$ = "" AND Ver = 0 THEN BEEP GOTO SID END IF IF LEN(a$) > 16 OR LEN(SID$) > 16 THEN PRINT "That entry is too long! (16 char max.)" GOTO SID END IF IF a$ = "" AND Ver > 0 THEN GOTO labno SID$ = a$ labno: PRINT PRINT "Lab Number: (format 'AAnnn') ["; ln1$; ln2$; INPUT "] ", a$ lnerr% = 0 IF a$ = "" THEN GOTO lablen IF LEN(a$) < 3 OR LEN(a$) > 5 THEN lnerr% = -1 ln1$ = UCASE$(LEFT$(a$, 2)) ' convert to upper case ln2$ = MID$(a$, 3, 3) lablen: IF (LEFT$(ln1$, 1) < "A" OR LEFT$(ln1$, 1) > "Z") THEN lnerr% = -1 IF (RIGHT$(ln1$, 1) < "A" OR RIGHT$(ln1$, 1) > "Z") THEN lnerr% = -1 IF VAL(ln2$) < 1 OR VAL(ln2$) > 999 THEN lnerr% = -1 IF lnerr% THEN BEEP GOTO labno END IF IF LEN(ln1$) <> 2 OR LEN(ln2$) > 3 OR VAL(ln2$) = 0 THEN BEEP GOTO labno END IF TDD: PRINT PRINT "Tube Diameter ["; TD; INPUT "] ", a$ IF a$ <> "" THEN IF VAL(a$) <> 30! AND VAL(a$) <> 200! THEN PRINT "Must be 30 or 200" GOTO TDD END IF TD = VAL(a$) END IF IF TD <> 200 AND TD <> 30 THEN GOTO TDD SLEEP 1 ' This new Routine automatically sets the next three parameters per the ' requirements requested by L.Poppe - 1/94 IF TD = 200 THEN DID = 50.8 CN = 14 AC1 = 14 AC2 = 3 END IF IF TD = 30 THEN DID = 12.7 CN = 16 AC1 = 16 AC2 = 3 END IF 'PRINT "The following parameters have been set to the normal defaults:" 'IMD: ' PRINT ' PRINT "Largest Micron Diameter Boundry ["; DID; 'AHE 1-18-94 ' INPUT "] ", a$ ' IF a$ = "" AND DID = 0 THEN ' PRINT "Must be entered" ' GOTO IMD ' END IF ' IF a$ <> "" THEN DID = VAL(a$) ' IC = 0 ' OK = 0 FOR i = 1 TO 38 IF DID = Dia(i) THEN OK = -1 IC = i END IF NEXT i ' IF NOT OK THEN ' FOR i = 1 TO 38 ' PRINT USING "####.### "; Dia(i); ' IF i MOD 6 = 0 THEN PRINT ' NEXT i ' PRINT ' PRINT "Must be one of the above." ' GOTO IMD: ' END IF 'ACN: ' PRINT ' PRINT "Associated Channel Number ["; CN; ' INPUT "] ", a$ ' IF a$ = "" AND CN = 0 THEN ' PRINT "Must be entered" ' GOTO ACN ' END IF ' IF a$ <> "" THEN ' CN = VAL(a$) ' OK = 0 ' FOR i = 1 TO 16 ' IF CN = i THEN OK = -1 ' NEXT i ' END IF ' IF NOT OK THEN ' PRINT "Must be 1 to 16" ' GOTO ACN ' END IF 'ACS: ' PRINT ' PRINT "Active Channels to be Recorded {example 14-3} ["; AC1; "-"; AC2; ' INPUT "] ", a$ ' IF a$ <> "" THEN ' ' B$ = MID$(a$, 3, 1) ' IF LEN(a$) < 4 THEN GOTO ACSERR ' IF B$ <> " " AND B$ <> "-" THEN GOTO ACSERR ' AC1 = VAL(LEFT$(a$, 2)): AC2 = VAL(RIGHT$(a$, 1)) ' GOTO ACSOK 'ACSERR: ' PRINT "Must be entered as NN-N or NN N . Please re-enter" ' GOTO ACS ' END IF 'ACSOK: ' OK = 0 ' FOR i = 9 TO 16 ' IF AC1 = i AND AC2 < i AND AC2 > 0 THEN OK = -1 'AHE 1-18-94 ' NEXT i ' IF NOT OK THEN ' PRINT "Entry "; AC1; "-"; AC2; " is not valid. Please re-enter" ' GOTO ACS ' END IF ' IF IC < AC1 THEN ' PRINT "Initial diameter too small for number of channels selected." ' GOTO IMD ' END IF ' ' DID= Initial Micron Dia. ' IC = Pointer to value DID in array DIA ' CN = Largest channel to be saved as data ' AC1= Number of channels ' AC2= Smallest chan to be saved as data ' OS = Offset IC-CN OS = IC - CN PRINT PRINT "Data will be recorded equivalent to Coulter Model TA II data" PRINT "from channels "; AC2; " to "; CN ' Added tilde per req LJP 10-98 PRINT "corresponding to lower boundries ~"; Dia(AC2 + OS); " to "; Dia(CN + OS); " microns." PRINT "and a maximum particle diameter of "; Dia(CN + OS + 1); " microns." IF Ver <= 0 THEN Ver = Ver + 1 CLS PRINT "PLEASE VERIFY THE DATA" PRINT GOTO Verify END IF PRINT INPUT "All entries correct? [Y] ", a$ IF a$ <> "" AND a$ <> "y" AND a$ <> "Y" THEN GOTO Verify Ver = 0 GOSUB PrintHeader 'PRINT HEADER ' ************** GET THE SAMPLES ************************* IVPC = 0 WaitForSamp: ' MSII new routine 94 AHE SELECT CASE PortNo% CASE 1, 2 PRINT " Please Send Raw Data - Press PRINT on Multisizer-II " GrabRawData PortNo% IF RawData(1) = -999 THEN 'test for abort condition BEEP PRINT PRINT "An error occured in the data transfer. " PRINT "Attempting retry now." PRINT GOTO WaitForSamp: END IF CASE 3 PRINT " Reading Raw Data - Please Wait" ReadRawData "MSII.DAT" END SELECT IF RawData(1) = -999 THEN 'test for abort condition BEEP PRINT PRINT "No raw data file MSII.DAT was found. Create the file or select" PRINT "a COM port for real time data logging." PRINT END END IF HeaderLables ' Read in the header text IF DiagMode% THEN PRINT PRINT "Raw Data - Header Portion" FOR i = 1 TO 78 PRINT RawData(i); " "; NEXT i PRINT AnyKey (Kee$) CLS PRINT PRINT "Raw Data - Counts Portion" FOR i = 79 TO 338 PRINT RawData(i); " "; NEXT i AnyKey (Kee$) END IF PRINT " Reading header file - Please Wait" HeaderInfo ' Convert the Header Data to text IF DiagMode% THEN CLS PRINT "Converted header information - Screen 1" PRINT FOR i = 1 TO 20 PRINT USING "### "; i; PRINT USING " \ \ "; HeaderLable$(i); HeaderData$(i) NEXT i AnyKey (Kee$) PRINT PRINT "Converted header information - Screen 2" PRINT FOR i = 21 TO 40 PRINT USING "### "; i; PRINT USING " \ \ "; HeaderLable$(i); HeaderData$(i) NEXT i AnyKey (Kee$) CLS PRINT END IF ' Check the tube size reported by the MS2 compared to the size entered ' by the operator and scold if necessary... IF RawData(4) <> TD THEN BEEP PRINT PRINT "############################ ERROR ################################" PRINT "# Orifice diameter reported by Multisizer does not match diameter #" PRINT "# Entered. Please correct and send data again. #" PRINT "#########################################################################" PRINT Ver = 1 TD = 0 GOTO Verify END IF ' Calculate Right edge sizes for all channels using Full Page, linear ' diameter law (1) per Coulter Multisizer II Ref. Manual, Appendix 2. PRINT " Calculating Size margins" SizeCalc Kc, NumChan, AppCurr, AppGain PRINT " Calculating Differential Volume Percentages" DiffVolume TotalCount, TotalVolume# PRINT PRINT "Kc = "; Kc PRINT "Num. Chan. = "; NumChan PRINT "Apperature I = "; AppCurr PRINT "Gain = "; AppGain PRINT PRINT "Total Count = "; TotalCount PRINT "Total Volume = "; TotalVolume# PRINT IF DiagMode% THEN AnyKey (Kee$) CLS PRINT " Info from Multisizer-II. using Count and Calculated Volumes" FOR i = 0 TO 256 IF (i MOD 20) = 0 THEN PRINT PRINT PRINT "Press 'ESC' to discontinue listing"; AnyKey Kee$ CLS IF Kee$ = CHR$(27) THEN EXIT FOR PRINT PRINT "CHAN.- MAX. SIZE- COUNT - DIFF VOL % " ELSE PRINT END IF count = RawData(i + 78) PRINT USING "### "; i; PRINT USING "###.### "; MS2Sizes(i); PRINT USING "####### "; count; PRINT USING "###.## %"; DifVol(i); NEXT i PRINT AnyKey (Kee$) CLS END IF COLOR WHITE + BLINK, BLACK PRINT "PLEASE WAIT"; COLOR BLACK, WHITE PRINT PRINT " Now normalizing the Multisizer-II count data to the equivalent " PRINT " Model Ta data formatted to USGS Sed Lab standards." PRINT AperDia = VAL(HeaderData$(2)) MakeTaData (AperDia) ' Copy Volume Percentages into old array 1- 94 FOR i = 1 TO 16 VP(i) = TaVolPct(i) PC(i) = TaCounts(i) NEXT i ' ******************** NORMALIZE DATA ********************** TVP = 0 FOR i = AC2 TO CN TVP = TVP + VP(i) NEXT i FOR i = AC2 TO CN VP(i) = (VP(i) / TVP) * 100 NEXT i PrintResults: ' ******************* PRINT THE RESULTS ******************** PRINT "============================ RESULTS ===========================" PRINT PRINT "Tube Diameter : "; TD IF PrintOn% THEN LPRINT IF PrintOn% THEN LPRINT "Tube Diameter : "; TD PRINT PRINT "Micron Dia. - Channel - Volume % - Population" IF PrintOn% THEN LPRINT IF PrintOn% THEN LPRINT "Micron Dia. - Channel - Volume % - Population" IF PrintOn% THEN LPRINT PRINT FOR i = 1 TO 16 DD(1, i) = 0: DD(2, i) = 0 ' ZERO DISK DATA ARRAY NEXT i j = 1 TPOP = 0 FOR i = AC2 TO CN DD(1, j) = Dia(i + OS) DD(2, j) = VP(i): j = j + 1 TPOP = TPOP + PC(i) PRINT USING " ####.### "; Dia(i + OS); PRINT USING " ## "; i; PRINT USING " ####.# "; VP(i); PRINT USING " #######"; PC(i) IF PrintOn% THEN LPRINT USING " ####.### "; Dia(i + OS); LPRINT USING " ## "; i; LPRINT USING " ####.# "; VP(i); LPRINT USING " #######"; PC(i) END IF NEXT i PRINT PRINT SPC(40); "Total Population = "; TPOP IF PrintOn% THEN LPRINT LPRINT SPC(40); "Total Population = "; TPOP LPRINT CHR$(12); END IF WhatNext: PRINT PRINT "S - Save the data R - Reprint E - Exit (Data no good) [S] "; INPUT a$ IF a$ = "" OR a$ = "s" OR a$ = "S" THEN GOTO LogToDisk 'SAVE TO DISK IF a$ = "R" OR a$ = "r" THEN GOSUB PrintHeader GOTO PrintResults END IF IF a$ <> "e" AND a$ <> "E" THEN GOTO WhatNext StartAgain: ' ************ CLEAN UP AND START NEXT ****************** CLS ln1$ = "PLEASE ": ln2$ = "ENTER" GOTO StartSamp LogToDisk: ' *********************** LOG TO DISK ******************** PRINT "SAVING DATA" OPEN "R", #1, "CLTR.NDX", 9 'changed to 9 for tube dia in CLTRQB93 AHE FIELD #1, 5 AS DISC$, 1 AS STAT$, 3 AS TubeDia$ GET #1, 1 ' READ REC #1 NFILES = VAL(DISC$) LSET DISC$ = STR$(NFILES + 1) PUT #1, 1 LSET DISC$ = ln1$ + ln2$ LSET STAT$ = "O" LSET TubeDia$ = RIGHT$(STR$(TD), 3) ' added tube dia 8-93 AHE PUT #1, NFILES + 2 CLOSE #1 a$ = ln1$ + ln2$ OPEN "R", #1, "CLTR.DAT", 254 ' Y2K QD$ was formatted as mm/dd/yy New format is mmddyyyy FIELD #1, 6 AS QM$, 5 AS QL$, 3 AS QT$, 16 AS QS$, 16 AS QP$, 16 AS QC$, 16 AS QR$, 16 AS QO$, 8 AS QD$, 8 AS QH$ FOR i = 0 TO 15 FIELD #1, (i * 9 + 110) AS DUMMY$, 5 AS QMD$(i), 4 AS QVP$(i) NEXT i LSET QM$ = " " LSET QL$ = ln1$ + ln2$ LSET QT$ = RIGHT$(STR$(TD), 3) LSET QS$ = SID$ LSET QP$ = PID$ LSET QC$ = CID$ LSET QR$ = SN$ LSET QO$ = OPN$ ' Y2K date format changed to mmddyyyy ~ Y$ is four char passed from ReadClock subroutine LSET QD$ = RIGHT$(STR$(Mo), 2) + DA$ + RIGHT$(Y$, 4) ' old format LSET QD$ = RIGHT$(STR$(Mo), 2) + "/" + DA$ + "/" + RIGHT$(Y$, 2) LSET QH$ = H$ + ":" + MI$ + ":" + S$ FOR i = 1 TO 16 LSET QMD$(i - 1) = RIGHT$(STR$(DD(1, i)), 5) LSET QVP$(i - 1) = MID$(STR$(DD(2, i)), 2, 4) NEXT i PUT #1, NFILES + 1 CLOSE #1 ' GO BACK FOR NEXT GOTO StartAgain ' ****************** ' ** Subroutines ** ' ****************** ReadClock: ' *************** Read system clock & convert **************** T$ = TIME$ D$ = DATE$ H$ = LEFT$(T$, 2) MI$ = MID$(T$, 4, 2) S$ = RIGHT$(T$, 2) Mo$ = LEFT$(D$, 2) Mo = VAL(Mo$) DA$ = MID$(D$, 4, 2) Y$ = RIGHT$(D$, 4) RETURN PrintHeader: ' *************** PRINT HEADER INFORMATION *************** IF PrintOn% THEN LPRINT "Lab Number "; ln1$; ln2$ LPRINT "Operator: "; OPN$; " Requested by: "; SN$ LPRINT "Cruise I.D. "; CID$ LPRINT "Project I.D. "; PID$ LPRINT "Sample I.D. "; SID$ ' Y2K Fixed Y$ for four digit year LPRINT H$; ":"; MI$; ":"; S$; " "; Mo$(Mo); " "; DA$; ", "; RIGHT$(Y$, 4) LPRINT END IF PRINT "Lab Number "; ln1$; ln2$ PRINT "Operator: "; OPN$; " Requested by: "; SN$ PRINT "Cruise I.D. "; CID$ PRINT "Project I.D. "; PID$ PRINT "Sample I.D. "; SID$ ' Y2K Fixed for 4 digit year PRINT H$; ":"; MI$; ":"; S$; " "; Mo$(Mo); " "; DA$; ", "; RIGHT$(Y$, 4) PRINT RETURN END ' ******************************** END OF PROGRAM ******************************* ' ************************************************************ ' ** Name: AnyKey ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Displays message on row 25: ** ' ** "Press any key to continue" and waits for ** ' ** a keypress. Returns the key character as A$ ** ' ** ** ' ** Usage: Needs no calling arguments ** ' ** ** ' ************************************************************ SUB AnyKey (a$) LOCATE 25, 1 COLOR WHITE + BLINK, BLACK PRINT "Press any key to continue"; DO a$ = INKEY$ LOOP WHILE a$ = "" COLOR BLACK, WHITE PRINT END SUB ' ************************************************************ ' ** Name: DiffVolume ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: Version # in main module includes date ** ' ** as: MMDDYY ** ' ** Description: This routine uses the median values ** ' ** between each of the the channel edge ** ' ** values (in diameters) multiplied by ** ' ** the particle counts within each channel ** ' ** to calculate differential volumes. ** ' ** These data are placed in the array: ** ' ** DifVol() which is shared. ** ' ** ** ' ** Usage: If no info here please see the line ** ' ** comments. ** ' ************************************************************ SUB DiffVolume (TotalCount, TotalVolume#) SHARED MS2Sizes() SHARED RawData() SHARED DifVol() ' OPEN "Size.Dat" FOR INPUT AS #1 TotalCount = 0 TotalVolume# = 0 FOR i = 0 TO 256 ' Dummy$ = INPUT$(4, #1) ' INPUT #1, MS2Sizes(i) count = RawData(i + 78) TotalCount = TotalCount + count IF i > 0 THEN TotalVolume# = TotalVolume# + count * Volume(MS2Sizes(i) - (MS2Sizes(i) - MS2Sizes(i - 1)) / 2) NEXT i ' CLOSE #1 FOR i = 1 TO 256 count = RawData(i + 78) SampVolume = count * Volume(MS2Sizes(i) - (MS2Sizes(i) - MS2Sizes(i - 1)) / 2) DifVol(i) = (SampVolume / TotalVolume#) * 100 NEXT i END SUB SUB GrabRawData (PortNo%) ' ************************************************************ ' ** Name: GrabRawData ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BASS ** ' ** ** ' ** Description: Reads Multisizer II data from a COM ** ' ** Port into raw data array RawData() ** ' ** which is shared. Tests for proper ** ' ** beginning of data character and de- ** ' ** limiters. ** ' ** Usage: Called with PortNo (1 or 2) ** ' ** ** ' ************************************************************ SHARED RawData() CLOSE #3 n = 0 ' zero index Error1% = FALSE ' reset error flag PORT$ = "COM1" IF PortNo% = 2 THEN PORT$ = "COM2" OPEN PORT$ + ":9600,N,8,1,ASC,CD,CS,DS,OP" FOR RANDOM AS #3 ' 9600 BAUD, NO PARITY, 8 DATA BITS, 2 STOP BITS, BINARY MODE ' SUPRESS TIMEOUT ON low DCD,CTS,DSR & OPEN SUCESSFUL ' count = 0 DO a$ = INPUT$(1, #3) ' get one character IF a$ = CHR$(2) THEN EXIT DO count = count + 1 IF count > 100 THEN EXIT DO LOOP ' PRINT "CHAR"; a$; " ASCII"; ASC(a$) PRINT "Receiving Data" IF a$ <> CHR$(2) THEN ' test for CTRL-B BEEP PRINT " ILLEGAL START CHARACTER - ABORTING COLLECTION" PRINT " Check communications setup and retry or restart program." SLEEP 4 RawData(1) = -999 ' set error condition Error1% = TRUE END IF DO WHILE NOT Error1% a$ = INPUT$(1, #3) ' get one character Var$ = "" ' zero the variable ' test for delimiters DO WHILE a$ <> ";" AND a$ <> CHR$(13) AND a$ <> CHR$(10) AND NOT EOF(3) Var$ = Var$ + a$ a$ = INPUT$(1, #3) ' get the next character LOOP ' loop until delimiter found IF Var$ <> "" THEN ' test for double delimiter n = n + 1 'PRINT n; "- "; Var$ ' for now, print it RawData(n) = VAL(Var$) ' store as real END IF IF n = 338 THEN EXIT DO ' last word - exit LOOP CLOSE #3 'FOR i = 1 TO 338 ' PRINT RawData(i); " "; 'NEXT i END SUB ' ************************************************************ ' ** Name: HeaderInfo ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Please see comments within this routine ** ' ** ** ' ** Usage: If no info here please see the line ** ' ** comments. ** ' ************************************************************ SUB HeaderInfo SHARED RawData() SHARED HeaderData$() ' Y2K Check STR$(RawData(3)) This item may be 2 digit year from Multisizer HeaderData$(1) = STR$(RawData(1)) + "/" + STR$(RawData(2)) + "/" + STR$(RawData(3)) ' Date HeaderData$(2) = STR$(RawData(4)) ' Orif Dia a$ = " Not Set" IF RawData(5) = 1 THEN a$ = " Automatic" IF RawData(6) = 1 THEN a$ = " Manual" HeaderData$(3) = a$ ' Setup 1 a$ = " Not Set" IF RawData(7) = 1 THEN a$ = " Sample" IF RawData(8) = 1 THEN a$ = " Blank" HeaderData$(4) = a$ ' Setup 2 a$ = " Not Set" IF RawData(9) = 1 THEN a$ = " Recall" IF RawData(10) = 1 THEN a$ = " New" IF RawData(11) = 1 THEN a$ = " Record" IF RawData(12) = 1 THEN a$ = " Kd" HeaderData$(5) = a$ ' Cal HeaderData$(6) = STR$(RawData(13)) ' Kd HeaderData$(7) = STR$(RawData(14) * 10 ^ RawData(15)) ' Size a$ = " Not Set" IF RawData(16) = 1 THEN a$ = " um" IF RawData(17) = 1 THEN a$ = " fl" HeaderData$(8) = a$ ' Units a$ = " Not Set" IF RawData(18) = 1 THEN a$ = " Auto" IF RawData(19) = 1 THEN a$ = " Manual" IF RawData(20) = 1 THEN a$ = " Off" HeaderData$(9) = a$ ' Cur/Gain HeaderData$(10) = STR$(RawData(21)) ' Ap. Curr. a$ = " Not Set" IF RawData(22) = 1 THEN a$ = " 1" IF RawData(23) = 1 THEN a$ = " 2" IF RawData(24) = 1 THEN a$ = " 4" IF RawData(25) = 1 THEN a$ = " 8" IF RawData(26) = 1 THEN a$ = " 16" IF RawData(27) = 1 THEN a$ = " 32" HeaderData$(11) = a$ ' Gain a$ = " Not Set" IF RawData(28) = 1 THEN a$ = " + (positive)" IF RawData(29) = 1 THEN a$ = " - (negative)" IF RawData(30) = 1 THEN a$ = " Alternate" HeaderData$(12) = a$ ' Polarity a$ = " Not Set" IF RawData(31) = 1 THEN a$ = " Manual" IF RawData(32) = 1 THEN a$ = " Time" IF RawData(33) = 1 THEN a$ = " Siphon" IF RawData(34) = 1 THEN a$ = " Channel" IF RawData(35) = 1 THEN a$ = " Total" HeaderData$(13) = a$ ' Control HeaderData$(14) = STR$(RawData(36)) ' Time HeaderData$(15) = STR$(RawData(37)) ' Chan Count HeaderData$(16) = STR$(RawData(38) * 10 ^ RawData(39)) ' Total Count a$ = " Not Set" IF RawData(42) = 1 THEN a$ = " 64" IF RawData(43) = 1 THEN a$ = " 128" IF RawData(44) = 1 THEN a$ = " 256" ' Channels HeaderData$(17) = a$ a$ = " Not Set" IF RawData(45) = 1 THEN a$ = " ON" IF RawData(46) = 1 THEN a$ = " OFF" HeaderData$(18) = a$ ' Auto Scale a$ = " Not Set" IF RawData(47) = 1 THEN a$ = " ON" IF RawData(48) = 1 THEN a$ = " OFF" HeaderData$(19) = a$ ' Edit a$ = " Not Set" IF RawData(49) = 1 THEN a$ = " ON" IF RawData(50) = 1 THEN a$ = " OFF" HeaderData$(20) = a$ ' Coin Corr HeaderData$(21) = STR$(RawData(51)) ' Volume HeaderData$(22) = STR$(RawData(52)) ' PRD HeaderData$(23) = STR$(RawData(53)) ' Menu HeaderData$(24) = STR$(RawData(54)) ' Time HeaderData$(25) = STR$(RawData(55)) ' n Raw HeaderData$(26) = STR$(RawData(56)) ' n CCC HeaderData$(27) = STR$(RawData(57)) ' ID Full Meuu HeaderData$(28) = STR$(RawData(58)) ' LHC HeaderData$(29) = STR$(RawData(59)) ' RHC HeaderData$(30) = STR$(RawData(60)) ' BCT HeaderData$(31) = STR$(RawData(61)) ' Law HeaderData$(32) = STR$(RawData(62)) ' ID Narrow Menu HeaderData$(33) = STR$(RawData(63)) ' Law HeaderData$(34) = STR$(RawData(64)) ' LHC HeaderData$(35) = STR$(RawData(65)) ' RHC HeaderData$(36) = STR$(RawData(66)) ' ID Window Menu HeaderData$(37) = STR$(RawData(67)) ' LHC HeaderData$(38) = STR$(RawData(68)) ' RHC HeaderData$(39) = STR$(RawData(69)) ' Orifice Len HeaderData$(40) = STR$(RawData(70)) ' Spare HeaderData$(41) = STR$(RawData(71)) ' Spare HeaderData$(42) = STR$(RawData(72)) ' Spare HeaderData$(43) = STR$(RawData(73)) ' Spare HeaderData$(44) = STR$(RawData(74)) ' Spare HeaderData$(45) = STR$(RawData(75)) ' Spare HeaderData$(46) = STR$(RawData(76)) ' Spare HeaderData$(47) = STR$(RawData(77)) ' Spare HeaderData$(48) = STR$(RawData(78)) ' Spare END SUB ' ************************************************************ ' ** Name: HeaderLables ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Reads text file MS_LABEL.DAT to get ** ' ** descriptive titles for each line of ** ' ** Multisizer II header data. These are ** ' ** stored in shared array HeaderLable$() ** ' ** Usage: No calling arguments ** ' ** ** ' ************************************************************ SUB HeaderLables SHARED HeaderLable$() OPEN "MS_LABEL.DAT" FOR INPUT AS #1 FOR i = 1 TO 48 LINE INPUT #1, HeaderLable$(i) ' PRINT HeaderLable$(i) NEXT i CLOSE #1 END SUB SUB MakeTaData (AperDia) ' ************************************************************ ' ** Name: MakeTaData ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: Version # in main module includes date ** ' ** as: MMDDYY ** ' ** Description: This routine uses the MS2Sizes array ** ' ** computed from the provided calibration ** ' ** data to convert the MS2 count data from ** ' ** the appropriate active channels into ** ' ** 14 channels (3 to 16) of Model Ta data. ** ' ** These data are placed in the arrays: ** ' ** TaCounts() and TaVolPct(). ** ' ** ** ' ** Usage: Called with Apperature size argument ** ' ** in order to establish initial micron ** ' ** diameter at 200 = 4.00 or 30= 0.630 ** ' ** Note that Ta channels 1 and 2 are ** ' ** intentionally left at zero in this ** ' ** version. ** ' ************************************************************ SHARED MS2Sizes() SHARED RawData() SHARED TaSizes() SHARED TaCounts() SHARED TaVolPct() SHARED DiagMode% RawOffset% = 78 IF AperDia = 200 THEN TaOffset% = 12 ' offset to Ta chan 1 IF AperDia = 30 THEN TaOffset% = 4 ' offset to Ta chan 1 IF AperDia <> 200 AND AperDia <> 30 THEN BEEP PRINT "Aperature Diameter Error in MakeTaData - Program Halted" END END IF IuD = TaSizes(TaOffset% + 2) ' get initial micron diameter SLEEP 2 IF DiagMode% THEN PRINT PRINT "Aperature Dia. = "; AperDia; PRINT USING " Initial uDia. =###.###"; IuD END IF ' Begin calculation TaCounts(1) = 0 ' always zero for consistency TaCounts(2) = 0 ' with old Ta data TotalCounts = 0 FOR i = 3 TO 16 ' we go for 14 channels even if ' top two won't be used later TaSizeLo = TaSizes(i - 1 + TaOffset%) ' get low & high limits TaSizeHi = TaSizes(i + TaOffset%) IF DiagMode% THEN PRINT "i,Ta lo, hi "; i, TaSizeLo, TaSizeHi ' now we must find the first MS2 chan upper size within the window ' note that MS2Sizes() contains UPPER channel margin FOR j = 1 TO 256 IF MS2Sizes(j) > TaSizeLo THEN EXIT FOR NEXT j LoMS2ptr% = j ' save the pointer to MS2 chan LoMS2Dat = RawData(j + RawOffset%) ' grab MS chan count data LoMsize = MS2Sizes(j - 1) ' get the MS chan. low margin HiMsize = MS2Sizes(j) ' and the MS chan. high margin ' calculate the fraction of the MS channel BELOW the Ta channel Mspan = HiMsize - LoMsize ' MS channel size OutSide = TaSizeLo - LoMsize ' size below window Factor = OutSide / Mspan ' fraction below window TaCountsLo = Factor * LoMS2Dat ' compute portion of counts ' below the Ta channel window IF DiagMode% THEN PRINT "j, LoMsi, HiMsi, MS count "; j; LoMsize, HiMsize, LoMS2Dat ' find the first MS2 chan upper size ABOVE the window FOR k = 1 TO 256 ' start at 1 in case its same as j IF MS2Sizes(k) > TaSizeHi THEN EXIT FOR NEXT k HiMS2ptr% = k ' save the pointer to MS2 chan HiMS2Dat = RawData(k + RawOffset%) ' grab MS chan count data LoMsize = MS2Sizes(k - 1) ' get the MS chan. low margin HiMsize = MS2Sizes(k) ' and the MS chan. high margin ' calculate the fraction of the MS channel ABOVE the Ta channel Mspan = HiMsize - LoMsize ' MS channel size OutSide = HiMsize - TaSizeHi ' size above window Factor = OutSide / Mspan ' fraction above window TaCountsHi = Factor * HiMS2Dat ' compute portion of counts ' above the Ta channel window IF DiagMode% THEN PRINT "k, LoMsi, HiMsi, Ms2Dat "; k; LoMsize, HiMsize, HiMS2Dat ' begin adding the MS channel counts to the Ta channel as appropriate TaCounts(i) = LoMS2Dat IF DiagMode% THEN PRINT "Talo "; TaCounts(i) ' test that low and high MS data are not the same and add (if true) IF HiMS2ptr% > LoMS2ptr% THEN TaCounts(i) = TaCounts(i) + HiMS2Dat IF DiagMode% THEN PRINT "TaLo + TaHi "; TaCounts(i) ' subtract out the count fractions outside the Ta window TaCounts(i) = TaCounts(i) - (TaCountsLo + TaCountsHi) IF DiagMode% THEN PRINT "TaLH - %out "; TaCounts(i) ' determine if any MS channels lie between the low and high MS chans. ' and add to the current Ta channel if appropriate. n% = (HiMS2ptr% - LoMS2ptr%) - 1 IF n% > 0 THEN ' add the intermediate counts ' to current Ta channel FOR j = (LoMS2ptr% + 1) TO (HiMS2ptr% - 1) TaCounts(i) = TaCounts(i) + RawData(j + RawOffset%) IF DiagMode% THEN PRINT "adding Chan, Counts "; j, RawData(j + RawOffset%) NEXT j END IF IF DiagMode% THEN PRINT "Ta + Intermediate "; TaCounts(i) PRINT SLEEP 1 END IF ' NOTE that TaCounts() may now contain non integer values for ' increased accuracy NEXT i ' Compute Ta Volume Percentages IF AperDia = 200 THEN ' kill Ta chans 15,16 TaCounts(15) = 0 TaCounts(16) = 0 END IF FOR i = 1 TO 16 count = TaCounts(i) j = i + TaOffset% TotalCount = TotalCount + count IF i > 0 THEN TotalVolume# = TotalVolume# + count * Volume(TaSizes(j) - (TaSizes(j) - TaSizes(j - 1)) / 2) NEXT i FOR i = 1 TO 16 count = TaCounts(i) j = i + TaOffset% SampVolume = count * Volume(TaSizes(j) - (TaSizes(j) - TaSizes(j - 1)) / 2) TaVolPct(i) = (SampVolume / TotalVolume#) * 100 NEXT i ' **** TEST **** IF DiagMode% THEN TotalPercent = 0 FOR i = 1 TO 16 j = i + TaOffset% PRINT USING "###.### "; i; TaSizes(j - 1); TaSizes(j); PRINT USING " #########.## "; TaCounts(i); PRINT USING " ###.###"; TaVolPct(i) TotalPercent = TotalPercent + TaVolPct(i) NEXT i PRINT PRINT "Total Volume Percent = "; TotalPercent END IF END SUB ' ************************************************************ ' ** Name: NthRoot ** ' ** Type: MAIN [ ] FUNCTION [ X ] SUB [ ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Returns the n'th root of variable v ** ' ** same as v to the 1/n th power ** ' ** ** ' ** ** ' ** Usage: Called with root n and variable v ** ' ** ** ' ************************************************************ FUNCTION NthRoot (n, v) ' return the n th root of variable v ' same as v to the 1/n th power NthRoot = v ^ (1 / n) END FUNCTION ' ************************************************************ ' ** Name: ReadRawData ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Reads a captured Multisizer II data ** ' ** file, FileName$, into raw data array ** ' ** RawData() which is shared. Tests for ** ' ** beginning of data character and de- ** ' ** limiters. ** ' ** Usage: Called with FileName$ ** ' ** ** ' ************************************************************ SUB ReadRawData (FileName$) SHARED RawData() CLOSE #1 n = 0 ' zero index Error1% = FALSE ' reset error flag OPEN FileName$ FOR INPUT AS #1 ' open data file a$ = INPUT$(1, #1) ' get one character 'PRINT A$ IF a$ <> CHR$(2) THEN ' test for CTRL-B BEEP PRINT " ILLEGAL START CHARACTER - ABORTING " SLEEP 4 RawData(1) = -999 ' set error condition Error1% = TRUE END IF DO WHILE NOT EOF(1) AND NOT Error1% a$ = INPUT$(1, #1) ' get one character Var$ = "" ' zero the variable ' test for delimiters DO WHILE a$ <> ";" AND a$ <> CHR$(13) AND a$ <> CHR$(10) AND NOT EOF(1) Var$ = Var$ + a$ a$ = INPUT$(1, #1) ' get the next character LOOP ' loop until delimiter found IF Var$ <> "" THEN ' test for double delimiter n = n + 1 ' PRINT n; "- "; Var$ ' for now, print it RawData(n) = VAL(Var$) ' store as real END IF IF n = 338 THEN EXIT DO ' last word - exit LOOP CLOSE #1 END SUB SUB ScreenPaint CLS FOR i = 1 TO 25 FOR j = 1 TO 80 IF (i MOD 6) = 0 AND (j MOD 12) = 0 THEN PRINT CHR$(237); ELSE PRINT CHR$(176); END IF NEXT j, i END SUB ' ************************************************************ ' ** Name: SizeCalc ** ' ** Type: MAIN [ ] FUNCTION [ ] SUB [ X ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: ** ' ** Calculate Right edge sizes for all channels using ** ' ** Full Page, linear diameter law (1) per Coulter ** ' ** Multisizer II Ref. Manual, Appendix 2. ** ' ** The SUB returns Kc, NumChan, AppCurr, AppGain and ** ' ** the array: MS2Sizes () as reals. ** ' ** MS2Sizes() returns particle diameters in um. ** ' ** ** ' ** Usage: Needs no valid calling arguments ** ' ** ** ' ************************************************************ SUB SizeCalc (Kc, NumChan, AppCurr, AppGain) SHARED HeaderData$() SHARED RawData() SHARED MS2Sizes() Kc = VAL(HeaderData$(6)) NumChan = VAL(HeaderData$(17)) AppCurr = VAL(HeaderData$(10)) '* 10 ^ -4 AppGain = VAL(HeaderData$(11)) FOR i = 0 TO 256 MS2Sizes(i) = 0 NEXT i FOR i = 0 TO NumChan ' NthRoot returns the N'th root (1st argument) of the 2nd argument ' i is the channel number index MS2Sizes(i) = (Kc * i) / (NumChan * NthRoot(3, AppCurr * AppGain)) 'PRINT MS2Sizes(i);" "; NEXT i END SUB ' ************************************************************ ' ** Name: Volume ** ' ** Type: MAIN [ ] FUNCTION [ X ] SUB [ ] ** ' ** Language: Microsoft QuickBASIC 4.00 or above ** ' ** Programmer: A. Eliason ** ' ** Date: 11-11-93 ** ' ** ** ' ** Module: CLTRMS2K.BAS ** ' ** ** ' ** Description: Returns spherical volume for a ** ' ** particle of diameter 'Dia'. ** ' ** ** ' ** ** ' ** Usage: Called with variable argument Dia ** ' ** ** ' ************************************************************ FUNCTION Volume (Dia) r = Dia / 2 Volume = (4 * PI * r ^ 3) / 3 END FUNCTION