THERMAL CONTROL APPARATUS AND METHOD

Abstract: Embodiments described herein provide methods and apparatuses for thermally controlling an instrument. According to one embodiment, an apparatus includes a heater and a source of electrical energy electrically connected with the heater for energizing the heater to produce thermal energy. A driver is electrically connected with the heater and the source of electrical energy for controlling application of electrical energy to the heater. A sensor is electrically connected with the heater for detecting thermal energy produced by the heater responsive to the electrical energy from the source of electrical energy. A controller is electrically connected with the driver and the sensor for controlling production of thermal energy by the heater responsive to electrical energy from the source of electrical energy. Another embodiment provides a method in which a heater is electrically connected with a relatively reduced thermal energy reference resistor. An amplifier operatively associated with the heater slews to a relatively reduced thermal energy value which is recorded in memory. An algorithm controlling the heater is updated. The heater is electrically connected with a detector for sensing thermal energy produced by the heater. The amplifier slews to a value associated with the detector.

Description: THERMAL CONTROL APPARATUS AND METHOD BACKGROUND OF THE INVENTION Embodiments described herein generally relate to an apparatus and a method for controlling temperature. More specifically, the embodiments relate to an apparatus and a method providing thermal control of an element of an analytical instrument. Analytical instruments are available for performing a number of functions. Some analytical instruments perform medical tests on biological samples, such as human blood and the like. These medical tests may determine if, for example, a human blood sample is infected with the AIDS virus. To perform the medical tests, the analytical instrument may mix the blood sample with another fluid, such as reagents and the like. The blood sample reacts with the added fluid. For some of these reactions between the added fluid and the blood sample to take place as intended, it may be desirable to maintain the blood sample/added fluid mixture at a specific temperature. The mixture may need to be kept at that specific temperature for a predetermined period of time. This time period may be referred to as an "incubation period." Similar concerns about appropriate temperatures for appropriate times may relate to the blood sample and the added fluid separately before mixing. To keep the blood sample/added fluid mixture at the desired temperature for the desired time period, the analytical instrument may be provided with a heater of sorts. The heater may be positioned near to a vessel holding the blood sample/added fluid mixture. A controller is associated with the heater for insuring that the heater supplies the vessel, and thus the mixture, with sufficient heat energy to keep the mixture at the desired, specific temperature for the desired time. If the mixture were not kept at the specific temperature for the specific time period, then the analytical instrument may not be able to perform the medical tests as intended. For instance, the instrument may not be able to obtain correct information about the blood sample. Assuming the blood sample were infected with the AIDS virus, if the blood sample/added fluid mixture were not kept at the desired temperature for the desired time period, then the analytical instrument may tell an operator of the instrument that the blood sample is not infected with the AIDS virus. This is undesirable. Many things may cause the mixture not to be kept at the desired temperature for the desired time period. For instance, the heater may degrade or age over time. The controller may have difficulty in controlling the heater. As the heater ages, the heater may not be able to provide the appropriate heat to the mixture for the proper time period. The heat applied to the mixture by the heater may change or vary over time. Th s, it can be appreciated that it is desirable to provide an apparatus and a method for controlling the heater and the heat applied to the blood sample, added fluid and mixture such that those things are kept at the proper temperature for the proper time period. SUMMARY OF THE INVENTION Embodiments described herein provide methods and apparatuses for thermally controlling an instrument. According to one embodiment, an apparatus includes a heater and a source of electrical energy electrically connected with the heater for energizing the heater to produce thermal energy. A driver is electrically connected with the heater and the source of electrical energy for controlling application of electrical energy to the heater. A sensor is electrically connected with the heater for detecting thermal energy produced by the heater responsive to the electrical energy from the source of electrical energy. A controller is electrically connected with the driver and the sensor for controlling production of thermal energy by the heater responsive to electrical energy from the source of electrical energy. Another embodiment provides a method in which a heater is electrically connected with a relatively reduced thermal energy reference resistor. An amplifier operatively associated with the heater slews to a relatively reduced thermal energy value which is recorded in memory. An algorithm controlling the heater is updated. The heater is electrically connected with a detector for sensing thermal energy produced by the heater. The amplifier slews to a value associated with the detector. In an additional embodiment, a method of thermally controlling an instrument includes electrically connecting a heater with a relatively increased thermal energy reference resistor. An amplifier operatively associated with the heater is allowed to slew to a relatively increased thermal energy value. The relatively increased thermal energy value is recorded in memory. An algorithm controlling the heater is updated. The heater is electrically connected with a detector for sensing thermal energy produced by the heater. The amplifier is allowed to slew to a value associated with the detector. A further embodiment provides a method of thermally controlling an instrument wherein a heater is energized such that the heater produces thermal energy. At least one of a relatively increased temperature reference value and a relatively reduced temperature reference value is consulted while the heater is energized to calibrate the heater. Yet another embodiment comprises a method in which a heater is energized with electrical energy to produce thermal energy. A thermal energy level produced by the heater is detected with a detector operatively associated with the heater. The detected thermal energy level is compared with a predetermined thermal energy level. The electrical energy applied to the heater is changed such that the detected thermal energy level is substantially similar to the predetermined thermal energy level . BRIEF DESCRIPTION OF THE DRAWINGS Fig. 1 is a general schematic block diagram of an apparatus and a method for thermal control; Figs. 2A and 2B are a schematic diagram of a driver comprising the apparatus shown in Fig. 1; Figs. 3A and 3B are a schematic diagram of a slave sensor comprising the apparatus of Fig. 1; Figs. 4A/1, 4A/2, 4B, 4C/1 and 4C/2 illustrate schematically a master sensor comprising the apparatus of Fig. 1; Fig. 5 is a schematic diagram of a circuit comprising part of the apparatus of Fig. 1; and Figs. 6A and 6B are a flow chart illustrating operation of the apparatus and method of Fig. 1. DETAILED DESCRIPTION OF PREFERRED EMBODIMENTS Embodiments disclosed herein relate to apparatuses and methods providing thermal control. The apparatuses and methods may be utilized in a number of employments. However, for the sake of clarity of understanding, the embodiments will be discussed with respect to their employment with an analytical instrument. For instance, the embodiments may be used with the instruments and methods disclosed in U.S Patent No. ' s 5,006,309, 5,089,424, 5,120,199, 5,185,264, 5,198,368 and 5,244,630. Those patents are assigned to the assignee of the present case and the disclosures thereof are specifically incorporated herein, in their entirety, by this reference. It is to be noted that elements of the disclosed embodiments may be combined in any appropriate fashion to arrive at yet further embodiments. Thus, the scope of the claims is not to be limited to the embodiments disclosed herein. To clarify relations among the apparatuses and the methods, both will be discussed simultaneously. One embodiment 10 of a thermal control apparatus and method is illustrated m Fig. 1. The embodiment 10 generally comprise-: a controller 12, a driver 14, a sensor 16, and a heater 18, shown in dotted lines in Fig. 1. The heater 18 comprises a source 20 of thermal energy and a detector 22 that detects thermal energy m the heater 18. The controller 12 is electrically connected with the driver 14 and the sensor 16. The driver 14 is electrically connected with the source 20 of thermal energy. The sensor 16 is electrically connected with the detector 22. A source 24 of electrical energy is electrically connected with the controller 12, the driver 14 and the sensor 16 for supplying those elements with electrical energy. In an exemplary embodiment, the controller 12 may be a computer having memory and running appropriate routines. As referred to herein, memory may be a RAM, a ROM, an EPROM, a SRAM and the like. In one particular embodiment, the controller 12 comprises a 68HC11 microcontroller available from Motorola (Schaumburg, Illinois) . The controller 12 may include a digital logic device and memory that are electrically connected with at least one of the driver 14 and the sensor 16. The controller 12 performs appropriate routines, discussed in detail later, for controlling thermal energy in the heater 18. The driver 14 generally controls application of electrical energy from the source 24 to the source 20 of thermal energy in the heater 18. Application of electrical energy by the driver 14 to the source 20 is directed by the controller 12. The driver 14 may comprise, in one embodiment, a solid state relay and the like. The sensor 16 monitors an electrical signal generated by the detector 22 indicative of thermal energy present in the heater 18. The sensor 16 sends a complementary signal to the controller 12 such that the controller 12 is provided with information representing the thermal energy present in the heater 18. The heater 18, in an exemplary embodiment, may comprise a thermally conductive body, made of a metal such as aluminum and the like, with which the source 20 is operatively associated. The source 20 may be operatively associated with the body through a suitable technique, such as adhesive and the like. The body, in some embodiments, may be constructed to provide at least one of a cover for an item processing path in the instrument, a mechanism for transferring thermal energy from the source 20 to the item being processed, and structural support for instrument components, such as dispensers, washers, aspirators, etc. The body is constructed and positioned to assist in providing the desired temperature for the desired time period to the item being processed, such as a biological sample and the like, by the instrument. In one embodiment, the source 20 of thermal energy may be an electrical heating element, such as a resistive foil heating element with a nominal resistance of about 232 Ohms and a voltage rating of about 120 Volts rmΞ . The source 20 may incorporate a thermal energy limiter, such as a self-resetting thermal limit switch and the like. In a specific embodiment, the self-resetting thermal limit switch may interrupt flow of electrical current through the source 20 when the temperature of the switch approaches about 80' Celsius and may reset to again allow current flow through the source 20 when the temperature of the switch approaches about 60' Celsius. The detector 22, in an exemplary embodiment, is operatively associated with the body through suitable means, such as an adhesive and the like. The detector 22 may be of any construction that provides an electrical signal indicative of the thermal energy associated with the heater 18. In one specific embodiment, the detector 22 may be a SDI-GR2101 resistive temperature detector available from SDI of Attleboro, Massachusetts. This resistive temperature detector has an electrical resistance R (in Ohms) of about R = 100 + 0.3908-T - 5.802x10-5.T= where T is the temperature in degrees Celsius. To provide greater understanding, a particularly specific embodiment will now be discussed. It is to be noted that the specific details given are for illustration only as do not limit the claims. Like reference numerals are used for similar structures to provide coherency. A particular embodiment is illustrated in Figs. 2A and 2B through 6A and 6B. Those Figures show an embodiment which provides thermal control for a plurality of, specifically six, item processing paths in an analytical instrument. At least one of the processing paths may not be thermally controlled as the other paths are controlled. Each processing path includes a plurality of, specifically eight, heaters 18. At least one driver 14 (Figs. 2A and 2B) and at least one sensor 16 (Figs. 3A and 3B or Figs 4A/1, 4A/2, 4B, 4C/1 and 4C/2) are dedicated to each processing path. Thus, one controller 12 is electrically connected with six drivers 14 and six sensors 16. One of the sensors 16 is a master sensor 46 (Figs. 4A/1, 4A/2, 4B, 4C/1 and 4C/2) which is discussed in detail later. All other sensors 16 associated with the master sensor 46 are slaves to the master 46. Each of the drivers 14 and sensors 16 are respectively electrically connected with suitable source 20 and detector 22 pairs. There is one source 20 and detector 22 pair for each of the eight heaters 18 along each of the six item processing paths. Each heater 18 comprises a body, a source 20 and a detector 22. As shown in Figs. 2A and 2B, each driver 14 contains a plurality, eight in an exemplary embodiment, of control devices 25. The control device 25 may be a solid state relay and the like. In an exemplary embodiment, the control device 25 is an about 140 Volt, about 3 amp, about 50/60 Hertz solid state relay, such as model 70S2-04-B available from Grayhill, Inc. of La Grange, Illinois. Each of the control devices 25 is electrically associated with a source 20 and determines application of electrical energy from the source 24 of electrical energy to the associated source 20 of thermal energy. The driver 14 may comprise a latch circuit 26. The latch circuit 26 may be a data storage device, such as a flip-flop array and the like. The controller 12 sends an electrical signal (digital) to the latch circuit 26. The latch circuit 26 is electrically connected with the control devices 25 such that the control devices 25 determine application of electrical energy from the source 24 of electrical energy to the source 20 of thermal energy responsive to a signal from the controller 12. Fig. 5 shows electrical connections among a plurality, specifically eight, of detectors 22 associated with one of the item processing paths. A source 28 of substantially constant electrical current provides a substantially constant electrical current of about 2.0 milliamperes through a relatively reduced temperature reference resistor 30, the detectors 22 and a relatively increased temperature reference resistor 32 which are electrically connected in series. The electrical voltage across each resistor 30 or 32 or detector 22 is the product of the current (about 0.002 amperes in an exemplary embodiment) and the resistance (in Ohms) of the detector 22 or resistor 30 or 32. This is an application of the well known formula Voltage = Current X Resistance. This voltage is conveyed by electrical connections on both sides of each detector 22 to an associated source signal selector 34 in the appropriate sensor 16 for the particular processing path. In a particular embodiment, the resistors 30 and 32 are precision resistors of nominal resistances. In an exemplary embodiment, the resistor 30 has a nominal resistance of about 111 Ohms while the resistor 32 has a nominal resistance of about 123 Ohms. Voltages across the resistors 30 and 32 are applied by electrical connections on both sides of the resistors 30 and 32 to all of the source signal selectors 34 in the sensor 16 associated with the appropriate processing path. The general construction of an exemplary embodiment of the slave sensor 16 is shown in Figs. 3A and 3B. The sensor 16 contains a plurality, specifically eight, station circuits 36. Each of the station circuits 36 includes a source signal selector 34, a prefilter 38, an amplifier 40 and a postfilter 42. The source signal selector 34 selectively electrically connects the associated station circuit 36 to one of two reference signals, corresponding to the relatively increased ar.j reduced temperatures, or to the detector 22 associated with a specific heater 18. In one embodiment, the source signal selector 34 may be a multiplexer. The controller 12 determines to which of the two reference signals or the detector 22 the station circuit 36 is connected. A specific embodiment of the prefilter 38 is a single pole lowpass filter with a cutoff frequency of about 226 Hertz. The amplifier 40 has a gain of about 19.96. A specific embodiment of the postfilter 42 is a single pole lowpass filter with a cutoff frequency of about 18 Hertz. Each station circuit 36 in a given sensor 16 is electrically connected with a station signal selector 44. The station signal selector 44, in an exemplary embodiment, may be a multiplexer. The station signal selector 44 selectively electrically connects an output of one of the station circuits 36 to the master sensor 46, illustrated schematically in Figs. 4A/1, 4A/2, 4B, 4C/1 and 4C/2. Comparison of Figs. 3A and 3B with Figs. 4A/1, 4A/2, 4B, 4C/1 and 4C/2 illustrates similarities and differences among the slave sensors 16 and the master sensor 46. The selective electrical connection performed by the station signal selector 44 is determined by the controller 12. The master sensor 46 comprises a channel signal selector 48 which selectively electrically connects the outputs of all station signal selectors 44 to a range selection device 50. The channel signal selector 48 may be a multiplexer. The range selection device 50 may be a substraction circuit that subtracts one of the two selectable signals from the output of the channel signal selector 48 and amplifies the resulting signal by a factor of about 16.68. Output of the range selection device 50 is applied to a 12-bit analog to digital converter 52 which is electrically connected with the range selection device 50. Output of the converter 52 is electrically connected to the controller 12. Further details of the embodiments disclosed herein may become clear with reference to the following operational description, which is given as an example only. The embodiment 10 maintains a desired temperature in a processing path within an instrument. In this embodiment, thermal control is effected m periodic temporal cycles of about 683 msec. In each cycle, the thermal energy associated with the processing path is detected, corresponding data manipulation occurs, and the heaters 18 for that processing path are energized in a manner appropriate to maintain the associated thermal energy at the desired value. All operations are controlled by digital electrical signals from the controller 12 to the other components in the system discussed above. Operation of the controller 12 is governed by an appropriate routine contained in memory available to the embodiment 10. Accordingly, the following example contains references, where appropriate, to portions of a source code, written in C, of the routine which is included at the end of this description and before the claims. Specifically, the following text refers to certain lines in the source code at illustrative locations. When a numbered STEP is encountered in the following text, reference should be made to the relevant portion of the source code, indicated by the same STEP number, to gain a more complete understanding of the routine. The routine begins with thermal energy or temperature detection. The temperature at each heater 18 is detected by the associated detector 22 and sensor 16. A voltage is generated across a detector 22 due to the substantially constant current of about 2.0 milliamperes from the constant current source 28 for the processing path corresponding to the heater 18. This voltage is applied to the source signal selector 34. During the temperature detection process, the source signal selector 34 monitors voltage across the detector 22 and applies that voltage to an associated prefilter 38. The prefilter 38 reduces electrical noise and applies the voltage to the amplifier 40. The amplifier 40 amplifies the electrical signal associated with the applied voltage by a factor of about 19.96 and sends the amplified signal through the postfilter 42 which further reduces electrical noise. The output of the postfilter 42 is one of the input signals of the station signal selector 44. The controller 12 sends an electrical signal (digital) to address inputs of the station signal selector 44 and the channel signal selector 48. Responsive to the signal from the controller 12, the selectors 44 and 48 cause voltage across the desired heater's 18 detector 22 to be sent to the range selection device 50. The range selection device 50 subtracts one of two voltages from the channel signal selector 48 output to provide a range, in an exemplary embodiment at least two ranges, of sensor operation. In an exemplary embodiment, a first range is approximately from about 5' Celsius to about 35' Celsius. A second range is approximately from about 30' C to about 60' C. The first range is utilized by the routine during the embodiment 10 startup phase. The second range is utilized by the routine during an operation control process. The subtractor circuit of the range selection device 50 shifts voltage from the detector 22 so that, when at a relatively low end of a selected temperature range (for example, about 5' Celsius during startup or about 30' Celsius during operation) , the resulting signal is at about a high end of the analog to digital converter 52 input range (about 10 volts) . The analog to digital converter 52 converts voltage at ts input to a 12 bit digital signal representing the temperature at the relevant heater 18 and sends this 12 bit digital signal to the controller 12. The controller 12 compares the 12 bit digital signal representing the temperature at the relevant heater 18 to a 12 bit reference signal, AD_REF, representing the desired temperature of the related item processing path • τ desιred ) • The reference signal is calculated as: AD_REF = 0.5 + K - (IG * FIXED) where FIXED = 100.0 + (0.3908*T deΞ i red ) - (0.0000580195*T desιred 2) STEP 2 and IG and K are constants for each heater 18 determined during calibration, as described later. The numerical difference between the output of the analog to digital converter 52 and AD_REF is statistically offset by about 8 hexadecimal counts and stored in a memory device as a variable called TMP_RESULT. The controller 12 also contains in suitable memory the values of TMP_RESULT for the relevant heater 18 that were stored from the previous, about 256, heater cycles. The sum of the previous, about 256, TMP_RESULT values, termed RANDY_SUM, is divided by a number equal to the previous number, about 256, of heater cycles to yield an average value of TMP_RESULT for the previous cycles. T e controller 12 multiplies the average value by f ve and adds the current value of TMP_RESULT to yield a numerical value RESULT, used to control application of electrical energy to the source 20 for the relevant heater 18. The application of electrical energy to the source 20 is controlled by determining the number of half-cycles of electrical energy that will be applied to the source 20. The application of a half-cycle of electrical energy is termed a pulse. A full heater cycle is defined as about 64 electrical half-cycles, so the maximum amount of electrical energy that could be applied to a given source 20 is about 64 pulses per heater cycle. The numerical result of the heater control algorithm (RESULT) determines the number of pulses of electrical energy per heater cycle in accordance with the following table: Numerical Result Pulses per Heater Cycle 0 or less 1 1 or 2 2 3 or 4 4 5 or 6 8 7 16 8 (or more in normal control) 32 9 or more (only during instrument 64 startup) STEP 6 The pulses for a given source 20 are spread out within the cycle to yield an approximately uniform duty cycle for each source 20. In a particular embodiment, there are a plurality of heaters 18, each assigned a number from 1 to 8 associated with each of the six processing paths. During control, in an exemplary embodiment, even numbered heaters 18, or the associated sources 20, only receive pulses on even numbered half-cycles, and odd numbered heaters 18, or the associated sources 20, only receive pulses on odd numbered half-cycles, so that no more than about 24 heater sources 20 are energized simultaneously. STEP 7 The heater control process is adjusted during the startup period, defined as the first 4 of 5 phases. The startup phases last a total of about 30 minutes following energization of the heater control system (about five minutes each for phases 1 through 3, and about fifteen minutes for phase 4) . Phase 5 constitutes operation. During phase 1, only the sources 20 for heaters 2 through 4 in each channel may be energized at about full power (about 64 cycles) and the remaining sources 20 are not energized. During phase 2, the sources 20 for heaters 2 through 4 may be energized up to about half power (about 32 cycles) , stations 5 and 6 may be energized up to about full power, and the other heater 18 sources 20 remain deenergized. During phase 3, the sources 20 for heaters 2 through 6 may be energized at up to about half power, the source 20 for heater 7 may be energized at about full power, and the source 20 for heater 8 is not energized. During phase 4 (as in operation phase 5), the sources 20 for heaters 2 through 8 may be energized at up to about half power. The source 20 for heater 1 in this exemplary embodiment is never energized. Referring to Figs. 2A and 2B, the controller 12 determines which heater sources 20 will be energized for the next electrical half-cycle, and sends this information to the relevant driver latch circuit 26. The latch circuit 26 stores this information until the next electrical half-cycle begins. The heater control devices 25 sense the beginning of the next electrical half-cycle (a zero crossing in the electrical energy supply voltage) and actuate in accordance with the data stored in the latch circuit 26 so that electrical energy is applied to the proper sources 20 for that electrical half-cycle. To further illustrate, a block diagram of the thermal control system is presented in Figs. 6A and 6B. The thermal control system can be calibrated as it operates. Specifically, an "on-the-fly" calibration scheme be used to automatically correct the thermal control system comprising the embodiment 10 for the effects of thermal irregularities or variances from the desired temperature, such as component aging and drift. In particular, this calibration scheme may be used to correct for long-term changes in the sensor circuits 16. The calibration scheme generally detects output (digital) resulting from measuring voltages across resistors 30 and 32 of a particular heater's 18 item processing path. The resistors 30 and 32 are assumed to represent the resistances of the detectors 22 for a relatively increased temperature condition (about 123 Ω) and a relatively reduced temperature condition (about 111 Ω) . The measured digital values are used by numerical algorithms executed by the controller 10. The values measured in each calibration remain in effect until the next calibration occurs. In an exemplary embodiment, calibration of the heaters 18 in each item processing path occurs within about 30 minutes. When a calibration cycle is finished, another calibration cycle begins. One heater 18 is calibrated at a time. During calibration, the source 20 for a heater 18 being calibrated is energized in a manor substantially similar to an average history of heater 18 operation during the previous (about eight) heater 18 cycles, as recorded in a history matrix which may reside in a suitable memory. The history matrix is not updated during calibration. Two values for each heater 18 used by the controller 12 and determined during calibration are: IG = t (digital output from measuring about 111 Ω resistor) - (digital output from measuring about 123 Ω resistor) ] / 12.0 and K = (IG * 111.0) + (digital output from measuring about 111 Ω resistor) A sequence of steps during calibration is as follows (referring to all of the Figures) : Step 1: The heater 18 to be calibrated is electrically disconnected from its detector 20 and is connected to the relatively reduced temperature reference resistor 30 by switching the heater's 18 source signal selector 34. Essentially, the relatively reduced temperature reference resistor 30 takes the place of the detector 22 in the relevant circuit. An average value of the history matrix is read by software when the heater 18 temperature is requested through steps 2-6. The history matrix is not updated during steps 2-6. Step 2: The amplifier 40 slews, in about a two second delay period, to the relatively reduced temperature reference value and stabilizes. Step 3 : An updated relatively reduced temperature reference value is recorded for the heater electronics (Figs. 3A, 3B, 4A/1, 4A/2, 4B, 4C/1 and 4C/2) being calibrated. Step 4: The control algorithm is updated using the value of the relatively reduced temperature reference reading taken during step 3, by updating K, IG and AD_REF. Step 5: The heater electronics are electrically disconnected from the relatively reduced temperature reference resistor 30 and is electrically connected to the detector 22 by switching the appropriate source signal selector 34. Essentially, the detector 22 has replaced the relatively reduced temperature reference resistor 30 in the relevant circuit. Step 6: The amplifier channel 40 to slews, in about a two second delay period, to the value of the heater 18 thermal energy detector 22 and stabilizes. Step 7 : The algorithm retrieves real time temperature information from the sensor 16, and the history matrix is updated. Step 8: All remaining heaters 18 undergo steps 1-7 using an associated relatively reduced temperature reference resistor 30. Step 9: Steps 1-8 are repeated using a relatively increased temperature reference resistor 32. Any "out of range" condition on any relatively decreased of increased reference is reported to an operator as an error by the controller 12. The above discussion shows how the apparatus and method described herein is able to self-calibrate during operation. The apparatus and method do not need to be shut down or interrupted for calibration. #include "debug. h" / * "" * " * / / * * "" * / CONSTANTS 7 #define ADC ( * (int * ) 0x7FFF) Λ address of AD result 7 #define LF ( * (char * ) 0x9800) / * A/D line frequency input port 7 #define TRACK_STAT_REG f (char * ) 0x2200) / * (en)/(dis)able tracks 7 #define PMUX ( * (char * ) 0x2300) Λ address of A/D muxes 7 #define SENS ( * (char * ) 0x9000) I * A/D temprature sensor input port 7 #define BUFFER_SIZE 10 / * size of input buffer 7 #define INIT_DELTA_TEMP 20 Λ # of counts from temprature error 7 #define FALSE 0 #define SIZE_HIST 8 / * must be a multiple of 2 and less than 32 7 #define COLD_REF 2 Λ value to send to smux for cold ref . resistor 7 #define HOT_REF 1 Λ value to send to smux for hot ref. resistor 7 #define VERSION 2.13 Λ used to check for corrupt NVRAM 7 #define COLD_REF_OHMS 111.0 #define HOT_REF_OHMS 123.0 #define HOT 1 #define COLD 0 #define LOW_W INDOW 0x80 / * or'ed with sensor before placing in PMUX register 7 #define HIGH_WINDOW 0 Λ or'ed with sensor before placing in PMUX register 7 #define MAXINT 0x7FFF r largest signed integer 7 #define NUM_SYS_TESTS 8 / * number of possible range tests 7 #define ONE_MINUTE 114 #define FIVE_MINUTES (ONE_MINUTE * 5) I * # of timer interupts = 5 minutes 7 #define FIFTEEN_MINUTES (ONE_MINUTE * 15) / * # of timer interupts = 15 minutes 7 #def ine M UX_DELAY 75 I * number of micro seconds to delay for AD to settle 7 #define NUM_CYCLES 64 #define NUM_PHASES 5 #define NUM_SENSORS_PER_TRACK 8 #define NUM_TRACKS 6 #define NUM_SENSORS (NUM_TRACKS * NUM_SENSORS_PER_TRACK) #define TRUE 1 #define DELTA_REF_OHMS (HOT_REF_OHMS - COLD_REF_OHMS) #define WARNING0 0 / * sensor is higher or lower than delta temp after a phase 7 #def ine WARNING1 1 Λ sensor temp is higher than +delta_temp. 7 #define WARNING2 2 / * sensor temp is lower than -delta emp. 7 #define IRQERROR 6 / * no irq interrupts for 25 ms 7 #define ATDERROR 7 Λ A/D is not responding in 1 ms 7 enum boolean {false, true}; enum get_type {hex, decimal, character}; / — * " " * " * «« .. «« / r • * / r MACROS 7 clear all compare flags & load output compare register with time 7 #def ine DELAY(time) { TFLG 1 = 0XFF; TOC2 = TCNT + ((time) » 3) ; } #define DISABLE_TIMER_INT TMSK2 &= 0x7F masks any timer interupts 7 #define ENABLE_RS232 SCCR2 |= 0x2C / * sets RS232 interupt mask 7 #define ENABLE_TIMER_INT TMSK2 |= 0x80 Λ sets timer interupt mask 7 #define FINISH_DELAY while ((TFLG1 & 0x40) == 0); see delay function 7 #define RAM_OK (version_1 == VERSION && init_data. version == VERSION) r 1 r / r STRUCTURES 7 struct sensor_struct int ref[2]; / * ref. resistor readings COLD_REF, HOT_REF 7 unsigned char offset; unsigned char gain; float ig; float k; float fixed; int ad_ref; float temp; * temperature as input via rs2327 signed char hist[SIZE_HIST]; Λ history of avgl 7 signed char avgl ; f amount of power required by this sensor 7 signed char avg2; Λ temporary avgl 7 unsigned char status; f bit array of range test results 7 int reading; * value read from sensor 7 signed int sum; Λ value of average reading 7 signed long randy_sum; / * The young model of accumulated averages 7 unsigned char warning; Λ bit array for warning type 7 int reserved[19]; I * reserved space 7 }; extern struct sensor_struct sensor[NUM_TRACKS][NUM_SENSORS_PER_TRACK]; struct systest_struct { char type; Λ ie: 0: testing sensors, HOT_REF: testing hot ref.) 7 char test_number; test id number 7 char window; int lojimit; int upjimit; char status ; / * track status bit array 7 }; Λ type = -1 marks end of array) 7 r from PROM to NVRAM: all data within this structure 7 Λ will be used to initialize RAM 7 struct prom_2_nvram { r NVRAM copy of SYS_TESTS array 7 struct systest_struct sys_test[NUM_SYS_TESTS]; int deltajemp; I * range sensor temperature may vary from target temp 7 float version; / * software version number 7 ); extern struct prom_2_nvram init_data; / ■ /"" * " * " ** ' rGLOBALVARIABLESLOCATED IN NVRAM7 extern int tempsjoaded; / * blanket temps, are loaded 7 extern char empty; I * empty queue flag 7 extern char front, rear; / * queue position markers7 extern int irq_count; I * #IRQ interrupts before irq_jnt_hdlr turns itself off 7 extern char phase; extern char restart, quit; I * rs232 flags to restart and quit input7 extern char s[BUFFER_SIZE]; I * string for error messages 7 extern unsigned char tag[NUM_TRACKS]; / * error tag bit = 1 = error 7 extern int time_counter; / * used to count time of each phase 7 extern float version l ; extern char histj-rtr; Λ index pointer for avgl histogram 7 extern signed char calibrating; / * sensor being calibrated 7 extern char cal_∞unt; / * # of times to call this function befor reading ref. resistor 7 extern char cal_val; Λ value to place in smux for HOT = 1 or COLD = 2 ref. resistor 7 extern signed char slewing; Λ sensor that is slewing during calibration 7 extern unsigned char track_status; one bit for each track (disabled == 1) 7 extern unsigned char track_warning; I * one bit for each track (warning == 1) 7 extern struct systest_struct * cold_test_ptr; extern struct systest_struct * hot_test_ptr; extern struct systest_struct * temp_test_ptr; / * * «•«« * •* * * / ............................... . j rCONSTANTSLOCATED IN PROM7 extern unsigned char * const track_output[];/ * pointers to each track address 7 extern const char last_sensor[]; extern unsigned char 'const smux_adr |[2]; / •****•* * * " " ** ** "/ / * " * ""7 Λ CONSTANTS COPIED FROM PROM TO NVRAM AT NVRAM INITIALIZATION 7 extern const struct prom_2_nvram INIT_DATA; /"*""* * "** " .......... ; / * * / #include <io6811.h> #include "htr.h" rCONSTANTSLOCATED IN PROM7 const char last_sensor[] = { r last sensor in phase 7 0, 3, 5, 6, 7, 7 }; r GLOBALS LOCATED IN NVRAM 7 struct sensor_struct sensor[NUM_TRACKS][NUM_SENSORS_PER_TRACK]; float version_1 ; / * one of two locations used to test RAM (keep seperate from version_2 7 int irq_count; / * #IRQ interrupts before irq_int_hdlr turns itself off 7 char phase; char restart, quit; / * rs232 flags to restart and quit input7 char s[BUFFER_SIZE]; / * string for error messages 7 unsigned char tag[NUM_TRACKS]; / * error tag bit = 1 = error 7 int time_counter; / * used to count time of each phase 7 char hist_ptr; f index for histogram 7 Λ forward reference to functions 7 void what_phase(); void calc_fix_adref(); void clr_data_segment(); void init_data_segment(); void init_sensors(); void prom2ram_copy(); , « — ... . ... — . .. ; void main() char e, pass, plate, track, plate_bit; turn_blankets_off () ; tempsjoaded = FALSE; DISABLE_TIMER_INT; r initialize 7 OPTION = 0x00; Λ A D power upon ADPU, Eclock drives A/DCSEL 7 HPRIO = 0X00; Λ set TOF interrupt to highest priority 7 BAUD = 0x30; Λ set baud rate to 9600 7 PACTL = 0x40; I * enable pulse accumulator 7 ENABLE_RS232; enable_interrupt(); clr_data_segment(); Λ Initialize segments 7 TRACK_STAT_REG = 0; Enable tracks 7 pause(ONE_MINUTE * 3); / * wait for blankets to cool down 7 while (tempsjoaded == FALSE) ; r wait for valid temps, data 7 test_system(); / * complete test of boards & sensors 7 r calibrate 7 calcjix_adref(); PMUX = 0; address sensor zero so rt will have settled 7 DELAY(MUXJ-)ELAY + 400); / * when we get around to reading it later 7 calc_power_req(HIGH_WINDOW, MUXJ3ELAY) ; phase = 0; while (TRUE) { if (phase++ == 0) calibrating = -1 ; else if (calibrating == -1 ) I * start on the fly' calibrations 7 { calibrating = cal_count = 0 ; Λ start with sensor zero 7 slewing = -1 ; Λ no sensors are slewing yet 7 cal_yal = COLD_REF; * begin with cold ref. resistor 7 } switch(phase) { ease l: case 2: case 3: time_counter = FIVE_MINUTES; Λ phases 1-37 ENABLEJNMERJNT; break; case 4: time_counter = FIFTEEN_MINUTES; Λ phase 47 ENABLEJTIMERJNT; break; default: bre*; } while ( (phase == 5) || time_counter ) cate_power_req(HIGH_WINDOW, MUXJDELAY); distribute _power(); } DISABLE ΓIMERJNT; r check for sensors that did not heat up correctly 7 for (track = 0; track < NUM TRACKS; track++) { plate Joit = 0x01 ; pass = tag[track]; for (plate = 0; plate <= last_sensor(phase]; plate++) { if (pass & plate J it) Λ tag == 1 if error 7 sensor[track][plate].warning |= (1 « WARNINGO); / * sensor warning 7 track_waming |= (1 « track); / * track warning 7 } platej-.it «= 1 ; / * next sensor 7 > ' } } /*"""* ***•••*« *" / / * / void calcjix_adref () { struct sensor_struct * s_ptr; float temperature; for (s_ptr = &sensor[0]; s_ptr < &sensor[0] + NUMJ5ENSORS; s_ptr++) { temperature = (s_ptr->offset - 128.0) / 50.0 + s_ptr->temp * (9833.44 + s _ptr->gain) / 9959.31 ; s_ptr->fixed = 100.0 + (0.390802 * temperature) + (-0.0000580195 * temperature * temperature); s_ptr->ad_ref = (0.5 + (s_ptr->k - s_ptr->ig * s_ptr->fixed)); } } Λ ......... ....... / * " * 7 void clr_data_segment() { clr_data_seg(); / * assembly routine to zero data segment 7 inrt_data_segment(); I * initialize data segment 7 } ; ... ........./ void init_data_segment() char i, j; char * p1 , * p2; I * version number for later tests of RAM 7 version_1 = VERSION; init_sensors(); prom2ram_copy(); / * initialize NVRAM from PROM 7 ; }..................... . . .... ............... 7 .......................... ....... #include <io6811.h> #include "htr.h" r CONSTANTS 7 #define INTEG 0.2 r CONSTANT OF FEED FORWARD INTEGRATION 7 #define Kp 1 / * proportional constant 7 #define Ki 5 / * integration constant 7 #define Kr 0 /* number of right shifts (aka: number of divide by 2's) 7 #define NUM_CALIBRATE_READS 4 / * number of reads before read ref. resistor 7 #rf SIZE_HIST == 16 #define AVGJ3HIFT 4 #endif #if SIZEJ-IIST == 8 #define AVGJ3HIFT 3 #endif #if SIZEJHIST == 4 #define AVGJ3HIFT 2 #endif #if SIZEJHIST == 2 #define AVGJ3HIFT 1 #endif r MACROS 7 I * determine index (either 0 or 1) for smux_adr 7 #define SMUXJNDEX(a) ( ((a) & OxOC) » 2 ) #define REFJNDEX(a) ( ((a) » 1 ) Λ 1 ) #define CAL_MASK(val, sen) ( (val) « (((sen) - ((sen) & OxOC)) « 1 ) #define ABS(a) ( (a) < 0 ? -(a) : (a) ) Λ CONSTANTS LOCATED IN PROM 7 unsigned char * const smux_adr[][2] = { r sensors 0 .. 3 7 Λ sensors 4..7 7 { (unsigned char * ) 0x2400, (unsigned char * ) 0x2440 }, { (unsigned char * ) 0x2480, (unsigned char * ) 0x24C0 }, { (unsigned char * ) 0x2500, (unsigned char * ) 0x2540 }, { (unsigned char * ) 0x2580, (unsigned char * ) 0x25C0 }, { (unsigned char * ) 0x2600, (unsigned char * ) 0x2640 }, { (unsigned char * ) 0x2680, (unsigned char * ) 0x26c0 } }; r GLOBALS 7 signed char calibrating; / * sensor being calibrated 7 signed char slewing; / * last sensor calibrated (still slewing) 7 char cal_courτt; / * # of times to call this function befor reading ref. resistor 7 char cal_val; / * value to place in smux for HOT = 1 or COLD = 2 ref. resistor 7 #rfdef DEBUG char xfl[13]; struct { int ref[2], unsigned char * address[2]; char va|2]; char sleJw[2}; char fill[4); filler to align nicely during debug 7 } x[NUM_TRACKS][NUMJ3ENSORS_PER_TRACK], ——i #endιf CAL STEP 2 CAL STEP 3 ' i ■ Λ / * " * * *" .I.I.i.. 7 void calc 3θwer_req(char window, int mux_delay) { signed char adjust, I CAL STEP 4 1~^ — I ιnt value, sum, track, 1 ■ signed int result, signed int tmp_result, unsigned char * tag_ptr, pass, colj-nt, char i, j, sens, struct sensor_struct * s_ptr, / * initialize pointers 7 tagu-.tr = tag, s_ptr = &sensorfO], ImeJreqO, I * make sure power is off 7 for (track •-- sens = 0, track < NUMJTRACKS track++) / * scan all sensors 7 { col_bιt = 1 , pass = 0, for (i = 0 ι < NUM _SENSORS_PER_TRACK, ι++, sens++, s_ptr++ colj-tit «= 1 ) { rt (calibrating ι= -1 ) * are we calibrating ? 7 { if (slewing == sens) Λ are we slewing f 7 { PMUX = (sens + 1 ) | window Λ yes address next sensor 7 DELAY(mux_delay), continue, f and skip this sensor 7 3 5 rf (sens == calibrating) are we calibrating this sensor "> 7 CAL STEP 1 A rf (cal_count == 0) Λ first time here for this sensor 7 { / * call this function 'cal_counf times before reading reference resistor 7 caL∞unt = NUM_CALIBRATE_READS #ιfdef DEBUG x[track][i] val[REFJNDEX(cal_val)] = CAL_MASK(cal_val i) x[track][i].address[REFJNDEX(caLval)] = smux_adr[track][SMUXJNDEX(ι)] x[track][ι] slew[REFJNDEX(cal_val)] = slewing, #endιf * smux_adr[track][SMUXJNDEX(ι)] = CAL_MASK(cal_val, i), / * set mux to ref resistor 7 r use average of histogram for power distribution 7 for (ι = sum = 0, j < SIZEJHIST, j++) CAL STEP 1 B 5 U ~1 sum += s_ptr->hιst[j], s_ptr->avg2 = s_ptr->avg1 = (sum » AVGJ3HIFT), } else if ( « al_count == 0) I * time to read ref resistor * -> 7 { T read the reference resistor 7 s_ptr->ref[REFJNDEX(cal_val)] = read_ref(), #ιfdef DEBUG x[track][i].ref[REFJNDEX(caLval)] = s_ptr->ref[REFJNDEX(caLval)], #endιf s_ptr->ad_ref = (0.5 + (s_ptr->k - s_ptr->ig * s_ptr->fixed)); * smux_adι track][SMUXJNDEX(i)] = 0; / * set smux to read sensor next time 7 slewing = sens; * give rt time to slew 7 r only calibrate sensors in earlier phases 7 if ((++calibrating & 0x07) > last__sensortphase - 1]) calibrating = (track + 1 ) « 3; / * 1st sensor on next track 7 DEl_AY(mux_delay); continue; / * and skip to next sensor 7 } } FINISH JDELAY; / * wait till mux and opamps settle 7 value = read_sensor(); / * average of two reads 7 / * has temp, varied beyond allowable limits ? 7 if (s_ptr->temp && s_ptr->status == 0 && phase) if (temp Jest _ptr && temp Jest j->tr->type != -1 ) sens ange(tempjest_ptr, s_ptr, ABS(s_ptr->reading - value), track); s_ptr->readιng = value; PMUX = (sens + 1 ) | window; / * address next sensor so rt can start settling 7 DELAY(mux delay); STEP 2 | tmp esult = (s_ptr->readιng - s_ptr->ad_ref + 8), if (ABS(tmp esult) < 0x100 ) STEP 13 s_ptr->randy_sum += tmp jesult - (s -.tr->randy_sum » 7); 4 0 } else s_ ptr->randy_sum = 0; STEP 4 j result = ((Kp * tmp jesult + (Ki * (s_ptr->randy_sum » 8))) » Kr ) » 4. if (result <= 0) s_ptr->avg1 = s_ptr->avg2 = NUM_CYCLES + 1 ; / * set for no power 7 else { sjotr->avg2 = 1 ; / * all sensors get first pulse 7 Λ set number of cycles to apply power 7 switch (result) . { ISTEP 5 | case 1 : s_ptr->avg1 = 16; break; Λ 32 cycles (2) 7 case 3: s_ptr->avg1 = 8; break; Λ 16 cycles (4) 7 case 5: s_ptr->avg1 = 4; break; Λ 8 cycles (8) 7 case 7: s_ptr->avg1 = 2; break; / * 4 cycles (16) 7 case 2: sj-»tr->avg1 = 16; break; Λ 32 cycles (2) 7 case 4: s_ptr->avg1 = 8; break; Λ 16 cycles (4) 7 case 6: s_ptr->avg1 = 4; break; I * 8 cycles (8) 7 case 8: s_ptr->avg1 = 1 ; break; f 2 cycles (32) 7 r power every cycle when on full 7 default: s_ptr->avg1 = 0: break; } r adjust to full power scale if appropriate for current phase 7 if ((phase < 4) && (i < last_sensortphase])) s_ptr->avg1 «= 1 ; if (sj3tr->avg1 < 0) Λ avoid negative avgl 7 s_ptr->avg1 = s_ptr->avg2 = NUM_CYCLES + 1 ; s_ptr->hist[hist_ptr] = s_ptr->avg1 ; / * update histogram 7 if (((unsigned int)result > initjjata.deltajemp) && ((unsigned int)result < 0x7ff )) / * close to temp or unused 7 { pass |= coljbit; / * tag == 1 means not close to temp 7 if (s_ptr->temp && sj->tr->status == 0) if (phase = 5) { s_ptr->warning |= (1 « WARNING1 ); * sensor warning 7 track vaming |= (1 « track); / * track warning 7 } else if (((unsigned int)result < -init iata. deltajemp) && ((unsigned int)result > 0x8000) && (phase == 5)) { if (s_ptr->temp && s_ptr->status == 0) { s_ptr->waming |= (1 « WARNING2); Λ sensor warning 7 track /varning |= (1 « track); Λ track warning 7 } } * tag_ptr++ = pass; / * load tag with results for track 7 FINISH JDELAY } / * read sensor zero so it has time to settle for next call to this function 7 PMUX = window; DELAY(mux_delay + 400); if (++hist_ptr >= SIZEJHIST) hist_ptr = 0; } / * * ; / * ** **** * / / * ***** / / * module: distpwr.c purpose: distribute power to sensors functions: distribute _power() programmer: modified by: date: 3/89 notes: main() will call calc_pwr eq() followed by distribute_power() endlessly, this module uses the information provided by calc_pwr eq() to distribute the proper amount of power to the correct sensors. * / / * ***** — * — * — *** ** ***** *** / #ιnclude <ιo6811 h> #ιnclude "htr h" / * **** * ** / / * * * / void dιstrιbute_power() { struct sensor_struct * s_ptr, * slew_ptr, char cycle, i, pass, coLbrt, sens, int track, for (cycle = 0, cycle < NUM_CYCLES, cycle++) { sens = 0, s__ptr = &(sensorfO]), for (track = 0 track < NUM TRACKS, track++) { col_bιt = 1 , pass = 0, for (i = 0, ι < NUM J3ENSORS J=ER_TRACK ι++, s ->tr++ sens++ colJ-.it «= 1 ) { f skip this one if temperature is zero 7 if (s_ptr->temp) { r if calibrating 'on the fly' make sure ref resistors * / r are still in range * / if (sens == slewing && cycle == 1 && cal_count == 4) { slew_ptr = &sensort0] + slewing, r do this test only rf it exists in sys JestQ and the test is enabled * / rf (slew_ptr->status == 0) / * don't test a disabled sensor * / { if (cold Jest_ptr && cold Jest jDtr->type '= -1 ) sens jange(cold Jest jDtr, slew_ptr, slew_ptr-> ref [COLD] track), if (hot Jest jDtr && hot Jest jatr->type ι= -1 ) sensjange(hotJest_ptr slew_ptr slew ->tr->ref[HOT] track) r rve it a pulse rf in full power * / STEP 6 l / * or every other row (not same parity) * / if ( (phase = 1) || (phase < 4) && (i > last_sensor[phase - 1]) || ((cycle Λ i) & 0x01) ) case2 pass &= 0x3F, break, case 3 pass &= 0x7F, break, default break; } s_ptr->avg2 = s ->tr->avg1 ; / * reload original 7 * track_output[track] = pass; / * output powermask 7 to guarantee that power was applied * / ; * / / ** * ****** / / * module: readsen.c purpose: read sensor functions: read_sensor(), read_ref() programmer: date: input: none output: average of two reads example: N/A notes: code is optimized for speed. * / / **** * * #include <io6811 .h> #include "htr.h" / * * **** read sensor twice; return average result 7 / * * [STEP 1 - MORE DETAIL I int read_sensor() char i, plate, track; int adr. time_out_cnt; time_out_cnt = 1000; PACNT = -2; / * set pactl to count two pulses from ADC * / TFLG2 = 0x20; Λ clear the overflow flag * / while (((TFLG2 & 0x20) == 0) && / * wart until A/D is finished * / (time_out_cπt > 0 )) { ~time_out_cnt; } if (timej-.ut -.nt > 0) { time -.ut .nt = 1000; adr = ADC; PACNT = -2; I * set pactl to count two pulses from ADC 7 TFLG2 = 0x20; Λ clear the overflow flag 7 while (((TFLG2 & 0x20) == 0) && Λ waft until A/D is finished 7 (time_out_cnt > 0 )) { -time_out_cnt; if (timej-.ut .nt > 0) return( (adr + ADC) » 1); turn )lankets_off(); for (track = 0; track < NUMJTRACKS; track++) { for (plate = 0; plate < (NUM_SENSORS_PERJTRACK ); plate++) sensor[track][plate].status |= (1 « ATDERROR); / * set sensor error 7 } TRACK J3TAT_REG = (track_status |= (1 « track)); / * disable and mark track * / } return(O); } / * * / r read sensor four times: return average result 7 / * / int read jef() or() ) » 1 ); * * / / / / * module: blksoff.c purpose: turn blankets off programmer: date: 2/89 input: none output: writes 0 to registers pointed to by track_output[] example: N/A notes: this code is optimized for speed. Don't replace it with a loop! conditional compile statements allow NUMJTRACKS to determine how many elements are in the array. * / #include <io6811.h> #include "htr.h" / * CONSTANTS LOCATED IN PROM * / unsigned char * const track_output[] = { / * pointers to each track address register * / (unsigned char * ) 0x2000, (unsigned char * ) 0x2040, (unsigned char * ) 0x2080, (unsigned char * ) 0x20C0, (unsigned char * ) 0x2100, (unsigned char * ) 0x2140 l; void turnJ>lankets_off() { #if NUMJTRACKS > 0 * track_output[0] = 0; #endif #if NUMJTRACKS > 1 * track_output[1] = 0; #endif #if NUMJTRACKS > 2 *track_output[2] = 0; #endιf #rf NUMJTRACKS > 3 * track_output[3] = 0; #endif #if NUMJTRACKS > 4 * track_output[4] = 0; #endιf #if NUMJTRACKS > 5 * track_output[5] = 0; #endif #if NUMJTRACKS > 6 * track_output[6] = 0; #endif #if NUMJTRACKS > 7 * track_output[7] = 0; #endif / * / * module: irq.c purpose: handle irq interrupt functions: linejreq(), irqjntjιdlr(); programmer: date: input: none output: none example: / * continue program execution after zero crossing * / lineJreqO; ..more code.. notes: code will loop within linejreq until zero crossing * / / * * #include <io6811.h> #include "htr.h" r CONSTANTS * / #define MINJRQ_COUNT 10 r MACROS 7 #defιne IRQJNTjON LF = 1 #defιne IRQJNTJDFF SENS = 1 /****** * * ****** ...../ / * ** * / void lineJreqO { char i, plate, track; unsigned int time_out_cnt; r wart for line to go high * / / * fall out of this loop when interrupt stops interrupting * / Λ or 60 ms elapsed * / tιme_out_cnt = 60000; do { ιrq_count = 1 , IRQJNTjON, ~tιme_out_cnt, } while ( (ιrc|_count <= 0) && (tιme_out_cnt > 0 ) ), r wait for line to go high * / if (tιme_out_cπt != 0) { tιme_out_cnt = 60000, ιrq_count = MINJRQ_COUNT, IRQJNTJON, do { -tιme_out_cnt, } while ( (irq count > 0) && (tιme_out_cnt > 0 ) ), } if (tιme_out_cnt == 0) { IRQJNT_OFF; turnj-.lankets -.ff(), for (track = 0; track < NUMJTRACKS; track++) { for (plate = 0; plate < (NUM_SENSORS_PERJTRACK ), plate++) { sensorftrackHplatel.status |= (1 « IRQERROR); / * set sensor error * / } TRACK _STAT_REG = (track_status |= (1 « track)), / * disable and mark track * / Λ function- ιrq_int_hdlr * / r purpose, handle an irq interrupt 7 r 7 / * input none 7 r output: none 7 / * theory when an interrupt occurs decriment irq_count until * / r it reaches zero then turn off the interrupt * / r / * notes: it is never neccessary to turn off this interrupt 7 r since rt turns itself off 7 / *** * * * ****** •«*•*«• / void irqjnt_hdlr() { if (--irq_count <= 0) IRQJNTJOFF; } / * / * module: systest.c purpose: system test of hardware for faults at program start programmer: date: input: data in sysjestfj output: writes status byte to TRACK_STATUS_REG each bit represents a track to (0) enable or (1 ) disable theory: sysjest is an array of data that drives the tests herein. See prom2ram.c for the format of the sysjest structure and to update its data. The array is downloaded from the PROM once when the NVRAM is initialized. The data may then be altered without changing the PROM in order to change the type of test, its data range, or to eliminate the test entirely. Each test expects its own unique format. The sensor and the ref. resistor tests expect the following data: test type = 0 for sensor, HOT/COLD_REF for ref. resistor test window = high or low lower limit of range check upper limit of range check and a byte for the result of the tests (which tracks failed) The driver/analog board test expects: test type 6 delta range that temperature reading must change during test low window tower limit upper window upper limit and a byte for the result To eliminate a test change its test type to -1. notes: if a sensor fails a test its entire track is disabled. a sensor is only tested if rt has been assigned a temperature during field testing the driver/analog test delta range can be changed to 0x10 by replacing its value. Since NVRAM won't be re-initialized unless it is corrupted, this change will be permanent. Additional tests can be added. Revisions: 10/19/92, ver. 103, Paul Ericson, Modified system test 6. * / / * #include <io6811.h> #include "htr.h" / * CONSTANTS * / #define CALIB_ADDITIVE_DELAY 10000 Λ extra delay during calibration * / r FORWARD REFERENCES TO FUNCTIONS * / int check ange(struct systest_struct * tjMr. char offset), void open_wιndow(char window), void faιl_sensor(struct systest_struct * t Dtr, struct sensor_struct * s_ptr, int track), / * MACROS 7 Λ determine offset of data into sensor array * / #defιne OFFSET(a) ((char * )&(sensor[0][0] a) - (char * )&(sensor[0])) Λ toggle window 7 #defιne SWAPJZVINDOW(w) ((w) = ((w) == LOW Λ.INDOW) f HIGH Λ/INDOW LOW Λ/INDOW) / * GLOBAL VARIABLES 7 unsigned char track_status / * one bit for each track (disabled == 1 ) 7 unsigned char track_warnιng, / * one bit for each track (warning == 1) 7 struct systest_struct * coldJest ->tr, * hot Jest tr, *tempJest r, / **** * ** * ** * * ***** / / * function test_system() purpose run all tests in sysjest[] input none output writes track status byte to enable/disable tracks Revisions 10/19/92, ver 103, Paul Ericson, Initialize secondary mux to select sensor before performing test 6 * / / * * / unsigned char mask[2], / * live sensors in (0)low window or (1 ) hi wind 7 int max[NUM_SENSORS_PER_TRACK], / * initial readings during test #67 int result[NUM_SENSORS_PER_TRACK], / * final readings during test #67 void test_system() char last_wιndow, offset, test, int i, j, track, unsigned char w, struct systest_struct * ptr, struct sensor_struct * s tr, phase = 0, ιnrt_sensors(), * initialize sensors * / track_status = 0, / * start out with a clean slate * / track_warnιng = 0 /* start out with a clean slate * / last window = 0, / * prevent 'on the fly' calibration range test unless test exists * / cold Jest otr = hot est tr = 0, turn _blankets_off () , Λ perform tests 7 for (test = 0, ptr = ιnιt_data.sysjest, test < NUMJ3YSJTESTS, ptr++, test++) switch (ptr->type) { case -1 : Λ skip this test 7 break; case 0: Λ test sensors * / last_window = ptr->window; open_window(ptr->window); / * give PMUX extra time to slew 7 calc Dθwer_req(ptr->window, CALIB -XDDITIVEJDELAY); / * read all sensors * / track_status |= check ange(ptr, OFFSET( reading)); break; case HOT_REF: Λ test ref. resistors * / hotjestj-.tr = ptr; / * will need for 'on the fly' calibrating * / r no break here... handle same as COLDJ^EF 7 case COLD_REF: if (ptr->type == COLD_REF) / * note: HOT_REF falls into here too 7 coldJest -.tr = ptr; / * for 'on the fly' calibrating * / read jef jesistors() takes forever! * / Λ don't read again unless window changed * / / * if (lastjrvindow != ptr->window) 7 { last_window = ptr->window; open_window(ptr->window); / * give PMUX extra time to slew * / readjef esistors(ptr->window); / * read the ref . resistors 7 } offset = ptr->type == HOTJ=tEF ? OFFSET(ref[Hθη) : OFFSET(ref[COLD]); track_status |= check ange(ptr, offset); break; case 6: Λ driver analog board correlation test 7 r reset secondary muxes to read sensors * / for (track = 0; track < NUMJTRACKS; track++) { * smux ad rack][0] = 0; * smux_adr[trackj[1] = 0; } pause(4); for (track = 0; track < NUMJTRACKS; track++) { get high & low window readings for all sensors this track * / mask[0] = mask[1] = 0; for G = 0; j < NUMj3ENSORS_PER_TRACK; j++) max[Q = 0; for (i = 0, w = HIGHJ/VINDOW; i < 2; i++, SWAP_WINDOW(w)) open /vindow(w); calc Dower _req(w, CALIB _ADDITI VE_DELAY) ; for 0 = 0, s )tr = &(sensorttrack][0]); j < NUMJ3ENSORS_PER_TRACK; j++, sjDtr++) { I * if sensor was assigned a temperature then test it 7 if (sjptr->temp) { #ifdef DEBUG sj-)tr->reserved[ϊ] = s ϊtr->reading; #endif r compare reading to correct (up/to) limit * / if (sj tr->readιng < ptr->upjιmιt && sj.tr->readιng > ptr->lo_lιmit ) { l (w = HIGH_WINDOW) { maxfj] = sj-rtr->readιng, mask[0] |= (1 «j), ) I * only do tow window if failed high window * / if (w == LOWJΛ/INDOW && max[j] = 0) { maxfj] = sjιtr->readιng, mas 1] |= (1 «|), } else if (w = LOWJΛ/INDOW && max[)] == 0) faιl_sensor(ptr, sjatr, track), } } } / * dont apply power to this track if no sensors need testing * / if (mask{0] || mas 1]) { r appfy power for this track * / * track_output[track] = (mask[0] | mask[1]), pause(30) , Λ wait 15 seconds 7 * trackj-.utput[track] = 0 , / * turn off power * / / * now read sensors to see if they've heated up sufficiently * / Λ NOTE, get them while there hot, get results and examine them later * / tor (i = 0, w = HIGHJW INDOW, i < 2, ι++, SWAP Λ/ INDOW(w)) { open_wιndow(w), calcjaower jeq(w. CALIB \DDITI VEJDELAY) , for 0 = 0, sjMr = &(sensorttrack][0]), | < NUMJ3ENSORS_PER_TRACK, j++, sj-tr++) if (mask[ι] & (1 « ))) / * get result from corτect window * / { resultfj] = sjΛr->readιng, #rfdef DEBUG sjΛr->reserved[4] = (track « 3) + j, sj)tr->reserved[ι + 2] = sj3tr->readιng, #endιf } } I * all sensors have been read from both windows * / / * if sensor failed to heat up suff iciently then track fails 7 for 0 = 0, s Jtr = &(senso rack]); j < NUM_SENSORS_PER_TRACK; )++, sj tr++) { Λ NOTE: ptr->window holds range delta for this test 7 rf (maxfj] && (max[fl - resultfj]) < ptr->window) fail_sensor(ptr, s rtr, track), } } break; case 7 temp Jest j-ttr = ptr, I * delta temp for 'on the fly' test 7 break. default: break; } } TRACK_STAT_REG = track_status; * (en)/(dis)able tracks * / open_window(HIGH_WINDOW); / * leave on a 'high note' 7 } /* / * function: check _range() purpose: test all sensor readings for out of range condition input: test: indexes into sysjest[test] offset: byte offset into sensor structure to find data to be tested output: updates sysjest result with track status byte for this test returns track status byte for this test * / / ******* *** ***** *** ****** / int check_range(struct systest_struct * tj->tr, char offset) char testj-.it, track, track J-.it, i; int val; struct sensor_struct * s >tr; sj tr = &sensort0]; trackj-.it =- 1 ; testj-.it = 1 « tjDtr->test_number; tjptr->status = 0; Λ start with status == ok 7 for (track = 0; track < NUMJTRACKS; track++, track J-rt «= 1) for (i = 0; i < NUMJ3ENSORS_PER_TRACK; i++, sj>tr++) { sj-ttr->status &= ~test_bit; / * clear bit (assume sensor will pass) * / val = * ((int * ) ((char * )(s_ptr) + offset)) ; / * test this value * / r note: only test sensor if it is assigned a temperature * / if (sj_»tr->temp && (val < tjMr->loJimit || val > tj-»tr->upjimit)) sjDtr->status |= test_bit; / * sensor failed this test 7 t >tr->status |= trac )rt; / * therefore track failed * / } } return (tj->tr->status); } / **** ...... / * function: open_window{) purpose: switch window and allow time for slewing input: window output: none 7 void open_window(char window) { r when switching windows allow extra time to slew * / PMUX = window; DELAY(100000); ' / ******* *** ******* * ****** / /*********** ♦ ««***«.** " ♦ « ♦ «" / void fail_sensor(struct systest_struct * tj>tr, struct sensorjstruct * sjDtr, int track) { s -ttr->status |= (1 « tj tr->testjiumber); Λ sensor failed ... 7 trackjjtatus |= (1 « track); Λ therefore track failed * / t tr->status |= (1 « track); record tracks failed this test * / } / ***** *** **** * ** / / * * •«« * « " ****"* * • " * / / * ** * **** * / / * module: readref.c purpose: read hot and cold reference resistors calculate ig, k, and fixed for all op amps programmer: date: input: window value to be or'ed with PMUX output: none example: On track 0 read hot reference for op amp 5 and read cold reference for op amp 4. smux[0][1] = 0x06; / * address secondary muxes from table above * / smux[0][0] = 0x00; pmux = 04 ; I * address primary mux for op amp 47 delay; read_sensor(); pmux = 5 ; repeat for op amp 5 * / delay; read_sensor(); * / / * ** * * / #include <io6811.h> #include "htr.h" #define LSB 1 / * least signif . byte of mask 7 #define MSB 0 / * most signif. byte of mask * / , / * function: readjef_resistors() * / r purpose: read hot & cold reference resistors * / T put results in sensor array 7 r input: window to be or'ed with PMUX 7 Λ output: none 7 Λ ..................................... — void read ef esistors(char window) { union { unsigned int i; Λ treat mask as an integer 7 unsigned char c[2]; Λ treat mask as a char * / } mask; char hot, cold, track, column; struct sensor_struct * sjptr; Λ hot == 0..7, cold == 7,1 ,2..6, mask == 0x8001 , 0x0006, ... OxcOOO 7 for (hot = 0, cold = 7. mask.i = 0x8001 ; hot < NUMj3ENSORS_PER_TRACK; { for (track = 0; track < NUMJTRACKS; track++) { * smux_adrftrack][0] = mask.cfLSB]; * smux adrttrack][1] = mask.c[MSB]; } pause(4) ; Λ wait 2 seconds 7 for (track = 0; track < NUMJTRACKS; track++) { PMUX = ((track « 3) + hot) | window; DELAY(MUXJOELAY); FINISH JDELΛY; sensor[track][hot].ref[HOT] = read_sensor(); PMUX = ((track « 3) + cold) | window; DELAY(MUX_DELAY); FINISH JDELAY; sensor[track][cold].ref[COLD] = read_sensor(); } mask.i = mask.i == 0x8001 ? mask.i = 0x0006 : mask.i « 2; ++hot; if (++cold = 8) cold = 0; } for (sj-ttr = &sensor[0]; sjrtr < &sensor[0] + NUMJ3ENSORS; s_ptr++) sj>tr->ig = (s .tr->ref[COLD] - sj)tr->ref[HOT]) / DELTA_REF_OHMS; s 3tr->k = (sj tr->ig * COLD_REFj-)HMS) + (sj->tr->ref[COLD]);

Claims: WHAT IS CLAIMED IS: 1. An apparatus for thermally controlling an instrument, the apparatus comprising: (a) a heater; (b) a source of electrical energy electrically connected with the heater for energizing the heater to produce thermal energy; (c) a driver electrically connected with tne heater and the source of electrical energy for controlling application of electrical energy to the heater; (d) a sensor electrically connected with the heater for detecting thermal energy produced by the heater responsive to the electrical energy from the source of electrical energy; and (e) a controller electrically connected with the driver and the sensor for controlling production of thermal energy by the heater responsive to electrical energy from the source of electrical energy. 2. An apparatus as defined m claim 1 wherein the driver comprises a solid state relay. 3. An apparatus as defined m claim 1 wherein the sensor comprises a source signal selector and a filter. 4. An apparatus as defined m claim 1 wherein the heater comprises an electrical heating element. 5. An apparatus as defined in claim 1 further comprising: (f) a detector for sensing thermal energy produced by the heater operatively associated with the heater. 6. An apparatus as defined in claim 5 wherein the detector is a resistive temperature detector. 7. An apparatus as defined in claim 1 further comprising: (f) a relatively reduced thermal energy reference resistor electrically connected with the sensor. 8. An apparatus as defined in claim 1 further comprising: (f) a relatively increased thermal energy reference resistor electrically connected with the sensor. 9. A method of thermally controlling an instrument, the method comprising the steps of: (a) electrically connecting a heater with a relatively reduced thermal energy reference resistor; (b) allowing an amplifier operatively associated with the heater to slew to a relatively reduced thermal energy value; (c) recording the relatively reduced thermal energy value in memory; (d) updating an algorithm controlling the heater; (e) electrically connecting the heater with a detector for sensing thermal energy produced by the heater; and (f) allowing the amplifier to slew to a value associated with the detector. 10. A method as defined in claim 9 further comprising the step of: (g) repeating steps (a) through (f) . 11. A method as defined in claim 9 further comprising the step of: (g) reporting heater status to an operator. 12. A method of thermally controlling an instrument, the method comprising the steps of: (a) electrically connecting a heater with a relatively increased thermal energy reference resistor; (b) allowing an amplifier operatively associated with the heater to slew to a relatively increased thermal energy value; (c) recording the relatively increased thermal energy value in memory; (d) updating an algorithm controlling the heater; (e) electrically connecting the heater with a detector for sensing thermal energy produced by the heatei , and (f) allowing the amplifier to slew to a value associated with the detector. 13. A method as defined m claim 12 further comprising the step of: (g) repeating steps (a) through (f) . 14. A method as defined in claim 12 further comprising the step of: (g) reporting heater status to an operator. 15. A method of thermally controlling an instrument, the method comprising the steps of: (a) energizing a heater such that the heater produces thermal energy; and (b) consulting at least one of a relatively increased temperature reference value and a relatively reduced temperature reference value while the heater is energized to calibrate the heater. 16. A method of thermally controlling an instrument, the method comprising the steps of: (a) energizing a heater with electrical energy to produce thermal energy; (b) detecting a thermal energy level produced by the heater with a detector operatively associated with the heater; (c) comparing the detected thermal energy level with a predetermined thermal energy level; and (d) changing the electrical energy applied to the heater such that the detected thermal energy level is substantially similar to the predetermined thermal energy level .

Inventors: KLOSTERMAN KURT, KLOSTERMAN, KURT
Applicants: ABBOTT LAB, ABBOTT LABORATORIES
Application year: 1995
Main classification: G05D23
IPC codes: G05D23