'***************This is the working program for checkout tests ************ 'Least anyone would think that any sane person would put all these comments 'into a BASIC program, everyone should know that I am writing this code while 'waiting for the printed circuit boards to arrive. I am frustrated and the 'only thing that I can think to do is to try to write code for hardware I 'don't have and hope that it is somehow related to what I finally need. ' 'Greetings computer professionals. What follows is a BASIC program. Please 'do not barf on your keyboard as it makes the keys sticky and gets under your 'fingernails. We expect that this program will run on almost any modern PC. 'It expecta a VGA adaptor. This means any machine that runs windows will 'probably run this program. We have tested it with the QB that comes with 'windows, so if you have windows you should be able to just run this. We do 'not include QB as that would be cheating. But I have included a compiled 'version of this program which can be run without a license. ' 'Sorry, you cannot run this under windows. Windows does not let you muck 'about with I/O. So boot up into DOS so that Windows does not steal all the 'I/O 'While this version of the program is for a single camera system, the code 'anticipates running a triplet. 'The program reads lines from the camera and writes them to a file and to 'the screen. ' 'Everything here runs from our home baked menu program. It is tree 'structured. A function key either performs an operation or goes to 'another menu. F9 always (almost) terminates the current operation and 'backs down to the previous menu. The label on the F9 key shows the 'menu you are in, and the menu you will go back to on hitting F9 'It is easy to add another menu. Menu1 is there and unused. Just copy 'it and follow the instructions. ' 'If you can't figure out what the function keys do from their 6 character 'labels, then find the code for that menu and read the 7 character comments 'that I have put there. It is easy to do. A BASIC CONTROL BREAK when in 'mystery menu will automatically stop you just below the code for that menu. ' 'We have included all the test routines we wrote while checking out the 'hardware. For once we have commented them so thay you can see what is 'being tested. Choose test from the first menu. If you can't figure out 'what is happening from the key labels, then look at the code where the 'key jumps to its subroutine. One can generate any of the pulses sent 'to the data card, load the aux register, cause continuous horizontal or 'vertical transvers, load a value into a dac, etc. One backs out of 'a continuous loop with F9 as with everything in the code. That is F9 'will (almost) always abort the current (long) operation and back down 'one menu '********************************************************************* 'Summary of Control Card I/O commands 'OUT (Basex+0), Data 'Loads the Output Control register 'OUT (Basex+1), Data '1) CableSelect=High Loads the Aux Output register '2) CableSelect=Low Sends Pulse to Data Card and resets ' the Strig FF 'OUT (Basex+2), Data 'Loads the DAC Clock Control register 'OUT (Basex+3), Data 'Loads the DAC registers 'A = INP (Basex+0) 'Reads a byte from the ADC determined by the Hi/Low bit 'A = INP (Basex+1) 'reads Ready FF statis. Note this is the same as the game port STRIG and is 'connected to both game port triggers. The low order 4 lines on this register 'can be hard wired to give a card ID. It also resets the Strig FF 'A = INP (Basex+2) 'Reads Aux in 'A = INP (Basex+3) 'Produces computer generated vertical transfer pulse, resets ready FF 'jumper selection on card allows selection of base addresses between '&H200 to &H3C and &H300 to &H3C (I think) '************************************************************************ 'following are the commands to the control card: 'OUT (Basex+0),SelectIt1 'loads the output selection register 'SelectIt1 bits have the following meaning: '0 (lo) low order pulse selection '1 high order pulse selection '2 byte 1=high byte, 0=low byte '3 bit 0 (low order) ADC multiplexer address '4 bit 1 ADC multiplexer address '5 bit 2 ADC multiplexer address '6 LED On '7 CableSelect 'broken down into great detail 'PulseSelect=RowShift selects row shift 'PulseSelect=StartADC starts ADC 'PulseSelect=ResetControl resets the control FF 'PulseSelect=SetControl sets the control FF 'ByteSelect=LowByte selects the low ADC byte for readout 'ByteSelect=HighByte selects the high ADC byte for readout 'MpxAddress=CameraOne connects mpx to camera 1 'MpxAddress=CameraTwo camera 2 'MpxAddress=CameraThree camera 3 'LEDVal=LEDOn turns on LED 'LEDVal=LEDOff turns off LED 'CableSelect=PulseIt Produces pulse at Camera Board 'CableSelect=LoadAux Loads Aux register 'code should contain: 'SelectIt1=PulseSelect+ByteSelect+MpxAddress+LEDVal+CableSelect 'each time one of the items is changed 'ClockSelect of &H0 disconnects VCO clock from the vertical transfer line. Vertical 'transfers are now made with INP (Basex+3) under program control. '******************************************************************* 'OUT (Basex+1),AuxData loads the auxilliary output register 'also produces pulse on the aux output connector 'the register is loaded at the trailing edge of the output pulse '******************************************************************** 'OUT (Basex+2),SelectIt2 'loads the DAC Clock Control register '0 low order clock speed selection '1 bit 1 clock speed selection '2 bit 2 clock speed selection '3 DAC A0 selection '4 DAC A1 selection '5 DAC A2 selection '6 Enable Write Temperature Control DAC '7 Enable Write VCO DAC 'more detail caused by my boredom waiting for PC boards 'ClockSelect=Zerox vertical shift comes from INP(Basex+Three) 'ClockSelect=Onex to Sevenx vertical shift comes from VCO 'DACSelect=VCOHigh select VCO high byte for load 'DACSelect=VCOLow select VCO low byte for load 'DACSelect=TempHigh select temp high byte for load 'DACSelect=TempLow select temp low byte for load 'code should contain: 'SelectIt2=ClockSelect+DACSelect 'each time one of the items is changed '************************************************************************ 'code starts here DEFINT A-Z DECLARE SUB GetALine () DECLARE SUB PlotALine () DECLARE SUB ReadTheDVM () DECLARE SUB RestoreALine () DECLARE SUB SaveALine () COMMON SHARED Basex AS INTEGER COMMON SHARED ByteSelect AS INTEGER COMMON SHARED CableSelect AS INTEGER COMMON SHARED CameraOne AS INTEGER COMMON SHARED CameraTwo AS INTEGER COMMON SHARED CameraThree AS INTEGER COMMON SHARED CCDLength AS INTEGER COMMON SHARED CCDLine() AS INTEGER COMMON SHARED ClockSelect AS INTEGER COMMON SHARED DACSelect AS INTEGER COMMON SHARED DataFileName AS STRING COMMON SHARED Datex AS STRING COMMON SHARED DVM() AS INTEGER COMMON SHARED Fivex AS INTEGER COMMON SHARED Fourx AS INTEGER COMMON SHARED LEDOff AS INTEGER COMMON SHARED GoBack AS INTEGER COMMON SHARED LEDOn AS INTEGER COMMON SHARED LEDVal AS INTEGER COMMON SHARED LinesToTake AS INTEGER COMMON SHARED LoadAux AS INTEGER COMMON SHARED Messloc AS INTEGER COMMON SHARED MpxAddress AS INTEGER COMMON SHARED Onex AS INTEGER COMMON SHARED PulseSelect AS INTEGER COMMON SHARED PulseIt AS INTEGER COMMON SHARED ResetControl AS INTEGER COMMON SHARED RowShift AS INTEGER COMMON SHARED RunComplete AS INTEGER COMMON SHARED SetControl AS INTEGER COMMON SHARED Sevenx AS INTEGER COMMON SHARED Sixx AS INTEGER COMMON SHARED SpareInteger() AS INTEGER COMMON SHARED SpareSingle() AS SINGLE COMMON SHARED StartADC AS INTEGER COMMON SHARED TempHigh AS INTEGER COMMON SHARED TempLow AS INTEGER COMMON SHARED TestCount AS INTEGER COMMON SHARED Threex AS INTEGER COMMON SHARED Timex AS STRING COMMON SHARED Twox AS INTEGER COMMON SHARED VCOHigh AS INTEGER COMMON SHARED VCOLow AS INTEGER COMMON SHARED Zerox AS INTEGER TYPE FileLine CCDLine(1 TO 790) AS INTEGER DVM(1 TO 5) AS INTEGER Timex AS STRING * 8 Datex AS STRING * 8 SpareSingle(1 TO 10) AS SINGLE SpareInteger(1 TO 10) AS INTEGER END TYPE COMMON SHARED kk AS FileLine '****************************************************************** 'here are constants for the tass cards Basex = &H300 ByteSelect = 0 CableSelect = 0 CameraOne = &H30 CameraTwo = &H20 CameraThree = &H38 CameraX = CameraTwo CCDLength = 790 ClockSelect = 0 DACSelect = 0 DataFileName$ = "Test" Fivex = 5 Fourx = 4 GoBack = 0 HighByte = &H4 LEDOff = &H0 LEDOn = &H40 LEDVal = 0 LinesToTake = 100 LoadAux = &H80 LowByte = &H0 Messloc = 1 MpxAddress = 0 Onex = 1 PulseSelect = 0 PulseIt = &H0 ResetControl = &H1 RowShift = &H0 RunComplete = 0 SetControl = &H3 Sevenx = 7 Sixx = 6 StartADC = &H2 TempHigh = &HB0 TempLow = &H88 TestCount = 10000 Threex = 3 Twox = 2 VCOHigh = &H70 VCOLow = &H48 Zerox = 0 '***** Here Create Special Out Valuse For Frequent Tasks ************* 'Set up for high byte and row shift for the center camera PulseSelect = RowShift ByteSelect = HighByte MpxAddress = CameraX LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RHBS = SelectIt1 'Set up to read the low byte from the center camera PulseSelect = ResetControl 'to avoid doing anything else ByteSelect = LowByte MpxAddress = CameraX LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RLB = SelectIt1 '********************************************************************* 'general constants and initial values here SCREEN 9 WIDTH 80, 43 REDIM CCDLine(0 TO CCDLength) AS INTEGER 'Storage for a single data line REDIM DVM(1 TO 5) AS INTEGER 'Other DVM stuff REDIM SpareSingle(1 TO 10) AS SINGLE REDIM SpareInteger(1 TO 10) AS INTEGER '******************************************************************* 'now set the constants for a standard data acquisition run VCOSetting = 25000 'the VCO DAC load for the starting operating point '******************************************************************* 'now set up for the start of a run '******************************************************************* 'Here starts a standard menu program to allow convenient use of the function keys 'we will use the first menu to route to major sub menus. 'use 2 for test, 3 for run, then go from there. One is left as an empty 'model so that it can be copied to make an additional menu 'now we fall into the menu program '***************************************************************************** '***************************************************************************** '*********************Enter First Menu************************ 'This is the first menu which is somewhat different bacause of exit Menuk = 0 StartMenu: KEY 1, " Test " KEY 2, " Run " KEY 3, " GAP " KEY 4, " CTC " KEY 5, "" KEY 6, "" KEY 7, "" KEY 8, "" KEY 9, STR$(Menuk / 10) + " EX" KEY 10, "" ON KEY(1) GOSUB Menu2 'to do tests ON KEY(2) GOSUB Dummy ON KEY(3) GOSUB GetAPicture 'to take a quick picture ON KEY(4) GOSUB ClearTheCharge 'sent 512 vertical shifts ON KEY(5) GOSUB Dummy ON KEY(6) GOSUB Dummy ON KEY(7) GOSUB Dummy ON KEY(8) GOSUB Dummy ON KEY(9) GOSUB BackSet ON KEY(10) GOSUB Dummy GOSUB TurnKeysOn GOSUB ClearLine KEY ON DO UNTIL hfo = 1 'GOSUB WorkLoop 'to look for something to do IF GoBack = 1 THEN GoBack = 0 LOCATE Messloc%, 2 GOSUB ClearLine INPUT "Enter exit (lower case) to save files, quit to end session, otherwise continue"; temp$ IF temp$ = "exit" THEN 'GOSUB SaveAll END ELSEIF temp$ = "quit" THEN LOCATE Messloc%, 2 GOSUB ClearLine INPUT "Are you sure that you want file changes lost? - enter YES if sure"; temp$ IF temp$ = "yes" THEN END ELSE END IF END IF IF CameBack = 1 THEN CameBack = 0 GOTO StartMenu END IF LOOP STOP '************************************************************************ 'this is an exemple of the standard menu structure 'Menuk is index into Keyx& key label matrix MenunSave holds key 'matrix index of where we came from GoBack=1 forces return to the 'previous menu. CameBack=1 causes relabel of keys and resetting 'of the key(n) gosubs. For a different menu change all the 1's 'to the new menu number - 5 places Menu1: Menu1Save = Menuk 'menu index we came from for this menu Menu1e: Menuk = 10 'menu index for this menu MenuSave = Menu1Save 'generic "came from" index for back key label KEY 1, " " KEY 2, " " KEY 3, " " KEY 4, " " KEY 5, " " KEY 6, " " KEY 7, " " KEY 8, " " KEY 9, STR$(Menuk / 10) + STR$(MenuSave / 10) KEY 10, " " ON KEY(1) GOSUB Dummy ON KEY(2) GOSUB Dummy ON KEY(9) GOSUB BackSet GOSUB TurnKeysOn GOSUB ClearLine KEY ON DO UNTIL hfo = 1 GOSUB WorkLoop IF GoBack = 1 THEN GoBack = 0 CameBack = 1 Menuk = Menu1Save RETURN END IF IF CameBack = 1 THEN CameBack = 0 GOTO Menu1e END IF LOOP 'end of standard menu structure '****************************************************************** 'we will use this menu for the tests Menu2: Menu2Save = Menuk Menu2e: Menuk = 20 MenuSave = Menu2Save KEY 1, "ADCTst" 'for ADC tests KEY 2, "PlsTst" 'for pulse tests KEY 3, "LdTemp" 'load the temp control DAC KEY 4, "LdVCO " 'loat the VCO control DAC KEY 5, " " ' KEY 6, " " KEY 7, " " KEY 8, " " KEY 9, STR$(Menuk / 10) + STR$(MenuSave / 10) KEY 10, " " ON KEY(1) GOSUB Menu4 ON KEY(2) GOSUB Menu3 ON KEY(3) GOSUB LoadTempDAC ON KEY(4) GOSUB LoadVCODAC ON KEY(5) GOSUB Dummy ON KEY(6) GOSUB Dummy ON KEY(9) GOSUB BackSet ON KEY(10) GOSUB Dummy GOSUB TurnKeysOn GOSUB ClearLine KEY ON DO UNTIL hfo = 1 GOSUB WorkLoop IF DeadMan% = 1 THEN OUT &H301, 0 IF GoBack = 1 THEN GoBack = 0 CameBack = 1 Menuk = Menu2Save RETURN END IF IF CameBack = 1 THEN CameBack = 0 GOTO Menu2e END IF LOOP '******************************************************* 'here we do tests that send pulses to the control card Menu3: Menu3Save = Menuk Menu3e: Menuk = 30 MenuSave = Menu3Save KEY 9, STR$(Menuk / 10) + STR$(MenuSave / 10) KEY 1, "VShift" 'continuous vertical shift pulses KEY 2, "HShift" 'continuous horizontal shift pulses KEY 3, "SetCon" 'set control ff KEY 4, "ResCon" 'reset control ff KEY 5, "VsInt " 'Interrupt controlled vertical shift KEY 6, "HsInt " 'Interrupt controlled horizontal shift KEY 7, "CtlBts" 'test the control bits KEY 8, "WatTmp" 'watch the temperatures KEY 10, "" ON KEY(1) GOSUB VerticalShift ON KEY(2) GOSUB HorizontalShift ON KEY(3) GOSUB SetControl ON KEY(4) GOSUB ResetControl ON KEY(5) GOSUB VerticalInterrupt ON KEY(6) GOSUB HorizontalInterrupt ON KEY(7) GOSUB TestControlBits ON KEY(8) GOSUB WatchTemperatures ON KEY(9) GOSUB BackSet ON KEY(10) GOSUB Dummy GOSUB TurnKeysOn KEY ON DO UNTIL hfo = 1 GOSUB WorkLoop IF DeadMan% = 1 THEN OUT &H301, 0 IF GoBack = 1 THEN GoBack = 0 CameBack = 1 Menuk = Menu3Save RETURN END IF IF CameBack = 1 THEN CameBack = 0 GOTO Menu3e END IF LOOP Menu4: 'Use this for ADC tests this menu checks each of the outputs of 'the multiplexer. ClrChg sends 512 vertical shift pulses to clear 'charge from the CCD 'read Cx just exercises that particular channel doing vertical shifts 'followed by shifting out the horizontal line. Menu4Save = Menuk Menu4e: Menuk = 40 MenuSave = Menu4Save KEY 1, " RdTEC" KEY 2, " RdTh2" KEY 3, " RdTh1" KEY 4, " Rd -5" KEY 5, " Rd C1" KEY 6, " Rd +5" KEY 7, " Rd C2" KEY 8, " Rd C0" KEY 9, STR$(Menuk / 10) + STR$(MenuSave / 10) KEY 10, "ClrChg" ON KEY(1) GOSUB ReadTheTEC ON KEY(2) GOSUB ReadThermister2 ON KEY(3) GOSUB ReadThermister1 ON KEY(4) GOSUB ReadTheMinus5 ON KEY(5) GOSUB ReadCCD1 ON KEY(9) GOSUB BackSet ON KEY(6) GOSUB ReadThePlus5 ON KEY(7) GOSUB ReadCCD2 ON KEY(8) GOSUB ReadCCD0 ON KEY(9) GOSUB BackSet ON KEY(10) GOSUB ClearTheCharge GOSUB TurnKeysOn KEY ON DO UNTIL hfo = 1 GOSUB WorkLoop IF DeadMan% = 1 THEN OUT &H301, 0 IF GoBack = 1 THEN GoBack = 0 CameBack = 1 Menuk = Menu4Save RETURN END IF IF CameBack = 1 THEN CameBack = 0 GOTO Menu4e END IF LOOP TurnKeysOn: KEY(1) ON KEY(2) ON KEY(3) ON KEY(4) ON KEY(5) ON KEY(6) ON KEY(7) ON KEY(8) ON KEY(9) ON KEY(10) ON RETURN TurnKeysOff: KEY(1) OFF KEY(2) OFF KEY(3) OFF KEY(4) OFF KEY(5) OFF KEY(6) OFF KEY(7) OFF KEY(8) OFF KEY(9) OFF KEY(10) OFF RETURN BackSet: GoBack = 1 RETURN Dummy: RETURN ClearLine: LOCATE Messloc%, 2 PRINT " " RETURN WorkLoop: 'put things here that need to be polled RETURN '***************************************************************************** '***************************************************************************** 'End of the standard function key menu program '************************************************************************* 'Note: everything from here on is a subroutine that is entered from a menu 'and which returns to the menu when done. '************************************************************************* Parameters: 'here load a file with the settings for a standard run 'put up the usual menu program RETURN BeginningStuff: LOCATE 1, 1 INPUT "Enter Number Of Lines to Take"; LinesToTake INPUT "Enter Data File Name"; DataFileName$ RETURN '************** The Data Taking Loop ******************* TakeData: DO UNTIL RunComplete = 1 'wait here till line ready IF VerticalTransfer = 1 THEN GOSUB ReadALine LOOP EndUpStuff: RETURN ReadALine: CALL GetALine CALL SaveALine CALL RestoreALine CALL PlotALine RETURN VerticalShift: ClockSelect = 0 'set up path GOSUB SelectIt2 'to set for computer generated vert xfer pulse OUT (Basex + Twox), SelectIt2 'to load DAC Clock Control register DO UNTIL GoBack = 1 'F9 will stop it a = INP(Basex + Threex) 'send vertical shift pulse FOR k! = 1 TO 100 NEXT k! LOOP RETURN VerticalInterrupt: 'Here to make vertical shifts and repeat ClockSelect = 0 'on the interrupt from the Ready FF GOSUB SelectIt2 OUT (Basex + Twox), SelectIt2 'to load DAC Clock Control register DO UNTIL GoBack = Onex 'F9 will stop it Waitx = Onex a = INP(Basex + Threex) 'send vertical shift pulse DO UNTIL Waitx = Zerox OR GoBack = Onex 'wait until interrupt resets Waitx z = INP(&H201) 'check for ready ff IF z < 128 THEN GOSUB TurnReadyOff LOOP LOOP 'done will produce strig to reset Ready TurnReadyOff: 'here on end of vertical shift PulseSelect = ResetControl 'send pulse and reset ready and event CableSelect = PulseIt 'set to send pulse to data card GOSUB SelectIt1 'put it together OUT (Basex + Zerox), SelectIt1 'load the output selection register OUT (Basex + Onex), Zerox 'send a pulse to reset ready Waitx = Zerox 'allow loop to continue sending a pulse RETURN HorizontalShift: PulseSelect = RowShift 'set data card load pulse path CableSelect = PulseIt 'set to send pulse to data card GOSUB SelectIt1 'put it together OUT (Basex + Zerox), SelectIt1 'load the output selection register DO UNTIL GoBack = Onex OUT (Basex + Onex), Zerox 'send a horizontal shift pulse 'FOR iii! = 1 TO 100 'NEXT iii! LOOP RETURN HorizontalInterrupt: PulseSelect = RowShift 'set data card load pulse path CableSelect = PulseIt 'set to send pulse to data card GOSUB SelectIt1 'put it together HZI = SelectIt1 'to increase speed DO UNTIL GoBack = Onex 'F9 will stop it OUT (Basex + Zerox), HZI 'load the output selection register Waitx = Onex OUT (Basex + Onex), Zerox 'send a horizontal shift pulse DO UNTIL Waitx = Zerox OR GoBack = Onex 'wait until interrupt resets Waitx z = INP(&H201) 'check for ready ff IF z < 128 THEN GOSUB TurnReadyOff LOOP LOOP 'done will produce strig to reset Ready RETURN LoadTempDAC: LOCATE 1, 1 INPUT "Enter command voltage"; TempDACv! TempDACv! = -TempDACv! TempDACv! = 65535 - TempDACv! * 3276.8 HighBytev! = INT(TempDACv! / 256) LowBytev! = TempDACv! - (256 * HighBytev!) LowBytev% = LowBytev! HighBytev% = HighBytev! OUT (&H302), &H48 OUT (&H303), LowBytev% OUT (&H302), &H70 OUT (&H303), HighBytev% RETURN LoadVCODAC: RETURN SelectIt1: SelectIt1 = PulseSelect + ByteSelect + MpxAddress + LEDVal + CableSelect RETURN SelectIt2: SelectIt2 = ClockSelect + DACSelect RETURN SetControl: PulseSelect = SetControl 'set data card set control path CableSelect = PulseIt 'set to send pulse to data card GOSUB SelectIt1 'put it together OUT (Basex + Zerox), SelectIt1 'load the output selection register OUT (Basex + Onex), Zerox 'send a pulse RETURN ResetControl: PulseSelect = ResetControl 'set data card reset control path CableSelect = PulseIt 'set to send pulse to data card GOSUB SelectIt1 'put it together OUT (Basex + Zerox), SelectIt1 'load the output selection register OUT (Basex + Onex), Zerox 'send a pulse RETURN ReadOutCCD: DO UNTIL GoBack = Onex ClockSelect = 0 'set up path GOSUB SelectIt2 'to set for computer generated vert xfer pulse OUT (Basex + Twox), SelectIt2 'to load DAC Clock Control register SOUND 1000, 1 p = 1 FOR i = 1 TO p a = INP(Basex + Threex) 'send vertical shift pulse FOR j = 1 TO 10 NEXT j NEXT i SOUND 500, 1 PixelCount = 0 DO UNTIL GoBack = Onex OR PixelCount = 794 'set up the paths OUT (Basex + Zerox), RHBS 'Set for Horizontal shift and start ADC OUT (Basex + Onex), Zerox 'send a horizontal shift pulse z = 128 DO UNTIL z < 128 OR GoBack = Onex 'wait until interrupt resets Waitx z = INP(Basex + Onex) 'check for ready ff LOOP HighOrder& = INP(Basex + Zerox) 'read the high byte OUT (Basex + Zerox), RLB 'Set path to read the low byte LowOrder% = INP(Basex + Zerox) 'read the low byte Valuex& = (256 * HighOrder& + LowOrder%) SELECT CASE Valuex& CASE IS < 32768 PrintValue& = Valuex& CASE ELSE PrintValue& = Valuex& - 65536 + 26700 END SELECT 'print it 'INPUT foox PixelCount = PixelCount + 1 IF PixelCount = 370 THEN PrintValuex& = PrintValue& LOOP 'LOCATE 5, 1 'PRINT USING "##### "; PrintValuex&'; HighOrder!; LowOrder! LOOP RETURN ReadThePlus5: MpxAddress = &H28 GOSUB ReadTheADC RETURN ReadTheMinus5: MpxAddress = &H18 GOSUB ReadTheADC RETURN ReadTheTEC: MpxAddress = &H0 GOSUB ReadTheADC RETURN ReadThermister2: MpxAddress = &H8 GOSUB ReadTheADC Th2! = Valuey! RETURN ReadThermister1: MpxAddress = &H10 GOSUB ReadTheADC Th1! = Valuey! RETURN ReadCCD0: PulseSelect = RowShift ByteSelect = HighByte MpxAddress = &H30 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RHBS = SelectIt1 PulseSelect = ResetControl 'to avoid doing anything else ByteSelect = LowByte MpxAddress = &H30 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RLB = SelectIt1 GOSUB ReadOutCCD RETURN ReadCCD1: PulseSelect = RowShift ByteSelect = HighByte MpxAddress = &H20 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RHBS = SelectIt1 PulseSelect = ResetControl 'to avoid doing anything else ByteSelect = LowByte MpxAddress = &H20 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RLB = SelectIt1 GOSUB ReadOutCCD RETURN ReadCCD2: PulseSelect = RowShift ByteSelect = HighByte MpxAddress = &H38 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RHBS = SelectIt1 PulseSelect = ResetControl 'to avoid doing anything else ByteSelect = LowByte MpxAddress = &H38 LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 RLB = SelectIt1 GOSUB ReadOutCCD RETURN TestControlBits: DO UNTIL GoBack = 1 OUT (Basex + Zerox), &H1 OUT (Basex + Zerox), &H0 LOOP RETURN ClearTheCharge: ClockSelect = 0 'set up path GOSUB SelectIt2 'to set for computer generated vert xfer pulse OUT (Basex + Twox), SelectIt2 'to load DAC Clock Control register p = 512 FOR i = 1 TO p a = INP(Basex + Threex) 'send vertical shift pulse FOR j = 1 TO 1000 NEXT j NEXT i RETURN ReadTheADC: 'DO UNTIL GoBack = Onex OR PixelCount = 794 'set up the paths PulseSelect = StartADC 'to start a conversion ByteSelect = HighByte LEDVal = LEDOff CableSelect = PulseIt GOSUB SelectIt1 OUT (Basex + Zerox), SelectIt1 'Set for Horizontal shift and start ADC OUT (Basex + Onex), Zerox 'send a horizontal shift pulse z = 128 DO UNTIL z < 128 OR GoBack = Onex 'wait until interrupt resets Waitx z = INP(Basex + Onex) 'check for ready ff LOOP HighOrder& = INP(Basex + Zerox) 'read the high byte PulseSelect = ResetControl ByteSelect = LowByte GOSUB SelectIt1 OUT (Basex + Zerox), SelectIt1 'Set path to read the low byte LowOrder% = INP(Basex + Zerox) 'read the low byte Valuex& = (256 * HighOrder& + LowOrder%) SELECT CASE Valuex& CASE IS < 32768 PrintValue& = Valuex& CASE ELSE PrintValue& = Valuex& - 65536 END SELECT LOCATE 40, 1 Valuey! = (PrintValue& + 19) * .000076# PRINT USING "#.#### "; Valuey!'; HighOrder!; LowOrder! 'LOOP RETURN GetAPicture: SCREEN 9, 0 WIDTH 80, 43 CLS 'LOCATE 34, 1 'PRINT " Log ADC Out Signed Val Offset Val" REDIM RMSArray!(0 TO 200, 1 TO 2) RMSCount = 0 DO UNTIL GoBack = 1 LOCATE 42, 1 PRINT VerticalLine = 0 DO UNTIL VerticalLine = 8 OR GoBack = Onex ClockSelect = 0 'set up path GOSUB SelectIt2 'to set for computer generated vert xfer pulse OUT (Basex + Twox), SelectIt2 'to load DAC Clock Control register p = 1 FOR i = 1 TO p a = INP(Basex + Threex) 'send vertical shift pulse q = 100 FOR j = 1 TO q NEXT j NEXT i PP! = 80000'76000 FOR i! = 1 TO PP! zz! = PP! NEXT i! 'SOUND 500, 1 REDIM HLine!(795) PixelCount = 0 DO UNTIL GoBack = Onex OR PixelCount = 794 'set up the paths OUT (Basex + Zerox), RHBS 'Set for Horizontal shift and start ADC OUT (Basex + Onex), Zerox 'send a horizontal shift pulse z = 128 DO UNTIL z < 128 OR GoBack = Onex 'wait until interrupt resets Waitx z = INP(Basex + Onex) 'check for ready ff LOOP HighOrder& = INP(Basex + Zerox) 'read the high byte OUT (Basex + Zerox), RLB 'Set path to read the low byte LowOrder% = INP(Basex + Zerox) 'read the low byte Valuex& = (256 * HighOrder& + LowOrder%) PrintValue& = 0 SELECT CASE Valuex& CASE IS < 32768 PrintValue& = Valuex& CASE ELSE PrintValue& = Valuex& - 65536 END SELECT Temp1 = PrintValue& PrintValuex& = (PrintValue&) 'was 29000 26650 before gain changeat room temp 25550) 'IF PrintValuex& < 1 THEN 'PrintValuex& = 1 'END IF HLine!(PixelCount) = (PrintValuex&) IF PixelCount = 377 THEN 'AND VerticalLine MOD 40 = 0 THEN LOCATE 1, 1 PRINT USING "#######.# "; HLine!(PixelCount); Valuex&; Temp1; PrintValuex&; VerticalLine RMSCount = RMSCount + 1 RMSArray!(RMSCount, 1) = PrintValuex& IF RMSCount > 25 THEN Temp1! = 0 FOR ij = 1 TO 25 Temp1! = Temp1! + RMSArray!(ij, 1) NEXT ij Temp2! = Temp1! / 25 Temp1! = 0 FOR ij = 1 TO 25 Temp1! = Temp1! + (RMSArray!(ij, 1) - Temp2!) ^ 2 NEXT ij Temp1! = SQR(Temp1! / 25) LOCATE 24, 1 PRINT USING "Mean Value = ####.## RMS Value = ####.##"; Temp2!; Temp1! GOSUB WatchTemperatures RMSCount = 0 END IF END IF PixelCount = PixelCount + 1 LOOP Sumx! = 0 FOR i = 200 TO 399 Sumx! = Sumx! + HLine!(i) NEXT i Sumx! = Sumx! / 200 FOR i = 1 TO 640 Colorx! = -INT((HLine!(i) - Sumx!) / 500) IF Colorx! < 0 THEN Colorx! = 0 PSET (i, VerticalLine + 328), Colorx! NEXT i VerticalLine = VerticalLine + 1 LOOP LOOP RETURN WatchTemperatures: 'DO UNTIL GoBack = 1 GOSUB ReadThermister1 GOSUB ReadThermister2 IF Th1! < .001 THEN Th1! = .001 Th1! = 1 * (15 / Th1! - 1) ThT1! = 25 + (223.1 - SQR(49774 - 4 * (13991 - 5967 * LOG(Th1!)))) / 2 IF Th2! < .001 THEN Th2! = .001 Th2! = 1 * (15 / Th2! - 1) ThT2! = 25 + (223.1 - SQR(49774 - 4 * (13991 - 5967 * LOG(Th2!)))) / 2 LOCATE 25, 1 PRINT USING "Water Temperature ###.### CCD Temperature ###.###"; ThT1!; ThT2! PRINT USING "Water Resistance ###.### CCD Resistance ###.###"; Th1!; Th2! 'LOOP RETURN SUB GetALine STATIC 'gets a line from the specified camera. We normally enter here after being 'interrupted by the result of a vertical shift. This is indicated by a game 'port ON STRIG GOSUB jump to sub. Enter here having turned off the game port 'interrupt. 'This code is for a single camera and takes advantage of the horizontal shift 'start of the ADC. Code for a triplet camera will have to select the different 'camera heads between conversions. PulseSelect = RowShift ByteSelect = LowByte MpxAddress = CameraTwo 'this code for a single lens camera LEDVal = LEDOff CableSelect = PulseIt SelectIt1A = PulseSelect + ByteSelect + MpxAddress + LEDVal + CableSelect 'SelectIt1A does a horizontal shift and the conversion is done after the 'hardware determined settling time. Conditions are left so a low byte wil 'be read OUT (Basex + Zero), SelectIt1 'while waiting for settling form, SelectIt1B. This sets for the read out 'of the high byte without producing a shift or starting a conversion PulseSelect = ResetControl 'since all combinations are used, this is the 'best do nothing command ByteSelect = HighByte SelectIt1B = PulseSelect + ByteSelect + MpxAddress + LEDVal + CableSelect i = 0 DO i = i + 1 'poll waiting for the conversion to be done exit if we have tried TestCount 'times or if we see done Testx = 0 DO UNTIL Testx = TestCount CheckIt = INP(Basex + One) IF CheckIt AND &H80 > 0 THEN Testx = TestCount ELSE Testx = Testx + 1 'if we get to the limit, then do give an error message END IF LOOP LowOrderByte = INP(Basex + Zero) OUT (Basex + Zero), SelectIt1B 'set to read the high byte, no shift HighOrderByte = INP(Basex + Zero) 'read the high byte OUT (Basex + Zero), SelectIt1A 'start the next shift 'put the bytes together from the last conversion and store in (i) TempValue& = 32768 - 256 * HighOrderByte - LowOrderByte CCDLine(i) = TempValue& 'else it will overflow the calculation LOOP UNTIL i = CCDLength CALL ReadTheDVM END SUB SUB PlotALine STATIC END SUB SUB ReadTheDVM STATIC 'reads the non camera values into the array V(). The mean of n 'readings is put in V() 'V(1) +15 'V(2) -15 'V(3) TEC current 'V(4) Water Temperature 'V(5) CCD Temperature END SUB SUB RestoreALine STATIC END SUB SUB SaveALine STATIC END SUB