Citation
A Distributed Control System for Low Pressure Plant Growth Chambers

Material Information

Title:
A Distributed Control System for Low Pressure Plant Growth Chambers
Creator:
MU, YANG ( Author, Primary )
Copyright Date:
2008

Subjects

Subjects / Keywords:
Sensors ( jstor )
Plant growth ( jstor )
Low pressure ( jstor )

Record Information

Source Institution:
University of Florida
Holding Location:
University of Florida
Rights Management:
Copyright Yang Mu. Permission granted to the University of Florida to digitize, archive and distribute this item for non-profit research and educational purposes. Any reuse of this item in excess of fair use or other copyright exemptions requires permission of the copyright holder.
Embargo Date:
5/31/2006
Resource Identifier:
436098722 ( OCLC )

Downloads

This item is only available as the following downloads:


Full Text

PAGE 1

A DISTRIBUTED CONTROL SYSTEM FOR LOW PRESSURE PLANT GROWTH CHAMBERS By YANG MU A DISSERTATION PRESENTED TO THE GRADUATE SCHOOL OF THE UNIVERSITY OF FLOR IDA IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF DOCTOR OF PHILOSOPHY UNIVERSITY OF FLORIDA 2005

PAGE 2

ACKNOWLEDGMENTS My greatest gratitude goes to my advisor, Dr. Ray Bucklin, for his knowledge, inspiration, and patience that navigated me through the whole process of my PhD study. I could not have gone this far without his help. I extend my gratitude to my committee members, Dr. Harwell Allen, Dr. Jim Leary, Dr. Pierce Jones, and Dr. Toshi Nishida, for the instruction and help they have given to me on my project. I would also like to thank Dr. Sencer Yeralan for sharing his expertise in the field of microcontrollers. I have special thanks for Bob Tokinson, who always had clever solutions to many practical problems. I am grateful to my family. Even so far away, they still gave me the love and support as they always did. I am also thankful for my friends, who made my life in Gainesville an enjoyable experience. ii

PAGE 3

TABLE OF CONTENTS page ACKNOWLEDGMENTS ..................................................................................................ii LIST OF TABLES .............................................................................................................vi LIST OF FIGURES ..........................................................................................................vii ABSTRACT .......................................................................................................................ix CHAPTER 1 INTRODUCTION........................................................................................................1 2 LITERATURE REVIEW.............................................................................................3 Measurement Fundamentals.........................................................................................4 General Measurement System...............................................................................4 Measurement Plan.................................................................................................5 Calibration.............................................................................................................6 Presenting Data......................................................................................................7 Fundamentals of Computer Control Systems...............................................................7 A/D and D/A Converters.......................................................................................8 Control Algorithm.................................................................................................9 Control System Structure....................................................................................10 Microcontroller...........................................................................................................11 Greenhouse Environment Control..............................................................................12 Temperature.........................................................................................................12 Temperature effects......................................................................................12 Temperature measurement...........................................................................12 Temperature control.....................................................................................13 Humidity..............................................................................................................14 Humidity effects...........................................................................................14 Humidity measurement................................................................................14 Humidity control..........................................................................................15 Radiation..............................................................................................................16 Photosynthesis and radiation........................................................................16 Radiation measurement................................................................................18 Radiation (PFD) control...............................................................................19 CO 2 ......................................................................................................................20 iii

PAGE 4

Photosynthesis and CO 2 ...............................................................................20 CO 2 measurement.........................................................................................20 CO 2 enrichment............................................................................................21 Low Pressure Plant Growth Studies...........................................................................21 Instrumentation for Low Pressure Plant Growth Chamber........................................25 3 OBJECTIVES.............................................................................................................30 4 MaTERIALS AND METHODS.................................................................................32 System Description.....................................................................................................32 Leakage Reduction.....................................................................................................35 Sensor Calibration......................................................................................................36 Preliminary Tests.................................................................................................36 RH sensor.....................................................................................................36 CO 2 sensor....................................................................................................37 O 2 sensor......................................................................................................38 Calibration Procedure..........................................................................................39 CO 2 sensor (GMM 221)...............................................................................41 CO 2 sensor (GMM 222)...............................................................................43 O 2 sensor......................................................................................................46 Control Algorithm......................................................................................................49 RH Control..........................................................................................................49 Gas Control..........................................................................................................51 Distributed Computer Control System.......................................................................52 System Structure..................................................................................................52 Load Cell Subsystem...........................................................................................54 Software......................................................................................................................55 Human to PC.......................................................................................................55 PC to Databases...................................................................................................56 PC to Microcontroller..........................................................................................57 Microcontroller to Adaptor boards......................................................................57 Plant Tests...................................................................................................................58 5 RESULTS AND DISCUSSION.................................................................................61 Leakage Test...............................................................................................................61 Sensor Calibration......................................................................................................61 Control Without Plants...............................................................................................63 Plant Responses to Different Conditions....................................................................65 Effects of Pressure and CO 2 Concentration on CO 2 Uptake Rate.......................65 Effects of Pressure and Light on CO 2 Uptake Rate.............................................66 Methodology for Developing Low Pressure Plant Growth Chamber........................67 6 CONCLUSIONS AND FUTURE WORK.................................................................69 Conclusions.................................................................................................................69 iv

PAGE 5

Future Work................................................................................................................70 Water Recycling..................................................................................................70 Bell Jar.................................................................................................................70 Plant Tests...........................................................................................................70 APPENDIX A MICROCONTROLLER CODE.................................................................................71 main.cpp......................................................................................................................71 function.c....................................................................................................................73 ADC_1241.c...............................................................................................................90 PIO.c...........................................................................................................................97 eeprom.c....................................................................................................................100 SystemTime.c...........................................................................................................103 memmap.asm............................................................................................................104 base.h........................................................................................................................105 ADC_1241.h.............................................................................................................106 PIO.h.........................................................................................................................107 eeprom.h...................................................................................................................107 SystemTime.h...........................................................................................................108 B PC CODE .................................................................................................................10 9 databaseview.cpp......................................................................................................109 databaseview.h..........................................................................................................127 database_01Set.cpp...................................................................................................130 database_01.h............................................................................................................132 OScopeCtrl.cpp.........................................................................................................133 OScopeCtrl.h............................................................................................................145 LIST OF REFERENCES.................................................................................................149 BIOGRAPHICAL SKETCH...........................................................................................152 v

PAGE 6

LIST OF TABLES Table page 2-1 PID Parameters Obtained from the Step-response Method........................................10 2-2 PID Parameters Obtained from the Ultimate-sensitivity Method..............................10 2-3 Different Types of Thermometers...............................................................................13 2-4 Different Types of Hygrometers..................................................................................15 4-1 Sensors........................................................................................................................34 4-2 CO 2 Sensor Reading...................................................................................................41 4-3 Slope and Intercept for Each Line...............................................................................43 4-4 CO 2 Sensor Reading...................................................................................................43 4-5 Slope and Intercept for Each Line...............................................................................44 4-6 O 2 Sensor Reading.......................................................................................................46 4-7 Slope and Intercept for Each Line...............................................................................48 4-8 Common Experimental Conditions............................................................................59 4-9 Experiment Pressure and Gas Conditions..................................................................59 5-1 Leakage Rates for LPPG Chamber..............................................................................61 5-2 CO 2 Sensor Test (GMM221).......................................................................................62 5-3 CO 2 Sensor Test (GMM222).......................................................................................62 5-4 O 2 Sensor Test.............................................................................................................62 5-5 Test Conditions for CO 2 Control................................................................................63 5-6 Test Conditions for RH Control.................................................................................63 5-7 Variables Measured and Controlled............................................................................68 vi

PAGE 7

LIST OF FIGURES Figure page 2-1 Components of a General Measurement System...........................................................5 2-2 Components of a Computer Control System.................................................................8 2-3 Photosynthetic Response to Wavelength.....................................................................16 2-4 Schematic Diagram of Michaelis-Menten Photosynthetic Light Response................18 4-1 Setup of the Experiment..............................................................................................33 4-2 RH vs. Pressure............................................................................................................37 4-3 CO 2 vs. Pressure..........................................................................................................38 4-4 O 2 vs. Pressure.............................................................................................................38 4-5 Setup of the Sensor Calibration...................................................................................40 4-6 CO 2 Reading vs. CO 2 %...............................................................................................42 4-7 Slope and Intercept vs. Pressure..................................................................................43 4-8 CO 2 Reading vs. Pressure............................................................................................44 4-9 Slope vs. CO 2 ppm.......................................................................................................45 4-10 Intercept vs. CO 2 ppm...............................................................................................45 4-11 O 2 reading vs. Pressure..............................................................................................47 4-12 Slope and Intercept vs. P...........................................................................................48 4-13 Relationships of Environmental Parameters..............................................................49 4-14 Flowchart of the Gas Control Algorithm...................................................................51 4-15 Schematic Diagram for the Distributed Control System...........................................53 4-16 User Interface............................................................................................................56 vii

PAGE 8

4-17 Schematic Diagram for the Software Structure.........................................................58 4-18 Soybean Plants Growing under Normal Atmosphere................................................59 5-1 CO 2 (kPa) Control Test................................................................................................64 5-2 CO 2 (ppm) Control Test...............................................................................................64 5-3 RH Control Test...........................................................................................................65 5-4 CO 2 Uptake Rates of Soybean under Different Total Pressure T= 25 C RH = 75% PAR = 530 mol/m2/s ppO 2 = 5kPa....................................66 5-5 CO 2 Uptake Rates of Soybean under Different Light Levels. T= 25 C RH = 75% ppO 2 = 5kPa...........................................................................67 viii

PAGE 9

Abstract of Dissertation Presented to the Graduate School of the University of Florida in Partial Fulfillment of the Requirements for the Degree of Doctor of Philosophy A DISTRIBUTED CONTROL SYSTEM FOR LOW PRESSURE PLANT GROWTH CHAMBERS By Yang Mu May 2005 Chair: Ray A. Bucklin Major Department: Agricultural and Biological Engineering A distributed control system was designed and developed for low-pressure plant growth chambers used to determine the effects of reduced pressure on plant growth. The system consisted of three sub systems, which were the adapter boards, the sub processor and the host processor. The adaptor boards read sensors and sent out control signals. The sub processor managed the adaptor boards and communicated with the host processor. The host processor, which was a PC, had a user friendly interface, recorded data in a database, and sent out control set points to the sub processor. Software was developed for both sub and host processors to communicate with hardware as well as human beings. The current system had only one growth chamber, but with its distributed structure, it can be easily extended to include more chambers. All the sensors were first tested under low pressure, and those that were found to be influenced by pressure, such CO 2 and O 2 sensors, were then recalibrated with premixed gases under different pressures. ix

PAGE 10

Total pressure, and partial pressures of CO 2 , O 2 , and N 2 , relative humidity were controlled, separately and efficiently. Short term plant tests were conducted to study the effects of different pressure, CO 2 and radiation on plant growth. This system was able to provide various environmental conditions that the tests required. Finally, an 8-step systematic approach was generalized for developing low-pressure plant growth systems. x

PAGE 11

CHAPTER 1 INTRODUCTION Long duration space missions to Mars will rely on life support systems capable of providing food, potable water and a breathable atmosphere. Higher plants have the ability to provide food, and recycle air and water. However, because of the differences between the environment of Mars and the requirements of Earth plants, enclosed environments such as special greenhouses will have to be used, in order for plants to grow on Mars,. A greenhouse operated at pressures less than earth sea level will reduce the stress on the structure and thus reduce the cost, risk and the leakage. For many years, NASA and other research institutes have conducted research on low-pressure greenhouses, in the two categories of science and engineering. Scientific research deals with issues like the following: Influence and limits of pressure, temperature, lighting, water, partial pressure of O 2 and CO 2 for plant growth; The mass transfer requirements, especially water flux, for plant growth as a function of total pressure and gas partial pressures. Plant microbial interactions and pathogens’ response to low O 2 , high CO 2 , and anticipated high relative humidity (vapor pressure deficit), especially in low total pressure. Engineering research deals with issues like Development and testing of environmental monitoring and control systems. Considerations related to the enclosures or structures. Operation and maintenance 1

PAGE 12

2 While overlap is essential between these two categories, they are to some extent independent of each other, which means scientific researchers do not have to consider much about structural issues. Thus, instead of building a greenhouse, which may take a lot of time and effort, a small growth chamber that meets the research requirements can be set up much easier and faster. A lot of research has been done with this way, but most studies were not well documented and cannot be reproduced from available information. One of the objectives of this research is to develop a systematic approach for building low pressure plant growth chambers, which are used to address the scientific issues in Mars greenhouses without too much concern about structural engineering aspects. This will be accomplished based on the experience in setting up a plant growth chamber as well as designing and developing a control system for it. Following this procedure, it is likely that science researchers, who are usually agronomists or plant physiologists, can set up their own systems without too much help from engineers.

PAGE 13

CHAPTER 2 LITERATURE REVIEW Long duration space missions to Mars will rely on life support systems capable of sustaining a required level of food, potable water and a breathable atmosphere. Higher plants, which have the ability to provide food, and recycle air and water, are good candidates to meet the above requirements. However, because of the differences between the requirements of Earth plants and the constitutions of Mars environment, which is cold (-143 C to about 17 C), with less atmosphere (1/150 of earth) and which is composed largely of CO 2 (95%) with traces of N 2 (2.7%), Ar (1.6%), O 2 (0.15%) , and water vapor (0.03%), in order for plants to grow on Mars, structures that resemble Earth greenhouses will be used. The purpose of greenhouses on Earth is to provide a confined space maintained at desirable environmental conditions for plants to grow. This concept can be extended to a Mars greenhouse, which not only needs to maintain the basic physiological requirements for plant growth, but also needs to be structurally sound to sustain the stresses produced by the difference between inside and outside pressure [Bucklin et al., 2004]. One approach for reducing structural stress is to reduce the operating pressure inside greenhouse, because the structural requirements to contain a pressure gradient decrease with decreasing pressure. However, growing plants under low pressure is not easy. Although past research showed that plants can survive at pressures under 10kPa or slightly lower, there are still a lot of questions to be answered. These questions include: What is the lowest pressure limit for plant growth? How plants will respond to changes in 3

PAGE 14

4 total pressure, partial pressures of CO 2 (ppCO 2 ) and O 2 (ppO 2 ), both separately and in certain combinations? In order to find answers for the above questions, small-scale low pressure plant growth (LPPG) chambers, instead of big greenhouses, are set up to complete research on plants. This chapter first reviews the fundamentals of measurement and computer control systems, and general issues in greenhouse environment control, then discusses current developments in LPPG study and instrumentation of LPPG chambers. The microcontroller, as a major control unit in this project, is also discussed. Measurement Fundamentals The primary objective in any measurement is to establish the value or the tendency of some variable [Figliola & Beasley, 2000]. But this is based on the value or the tendency suggested by the measurement. So how is the relationship between the real value of a variable and the measured value established? How can a measurement plan be devised so that the measurement provides the unambiguous information sought? How can a measurement system be used so that engineers can easily interpret the measured data and be confident in their reading? These are a few of the most important measurement questions. General Measurement System Figure 2-1 is the general template of a measurement system. Basically such a system consists of part or all of three stages: 1) the sensor-transducer stage; 2) the signal-conditioning stage; 3) the output stage. These stages form a bridge between the input to the measurement system and the system output, a quantity that is used to infer the value of the variable measured. The sensor is an element that uses some natural physical law to sense the variable being measured. The transducer converts this sensed information into detectable signal

PAGE 15

5 form, which might be electrical, mechanical, optical or other forms that can be easily quantified. The term “transducer” is often used in reference to a packaged device, which may contain both a sensor and a transducer, and even some signal conditioning elements. Sensor selection, placement and installation are particularly important because all the information from the measured variable is indicated by what is actually sensed by the sensor. The signal conditioning equipment takes the transducer signal and modifies it to a desired form. This optional intermediate stage might be used to perform tasks such as signal amplification and noise reduction. The output stage provides an indication of the value of the measurement. The output equipment might be a simple readout display or marked scale, or it might contain devices that can record the signal for later analysis. Figure 2-1. Components of a General Measurement System Measurement Plan A measurement plan usually has the following three steps: Signal Conditioning Stage Sensor Stage Transducer Stage Output Stage Calibration Process

PAGE 16

6 1. Parameter Design Plan. This is the test objective and identification of process variables and parameters and a means for their control. 2. System and Tolerance Design Plan. This is the selection of a measurement technique, equipment, and test procedure based on some preconceived tolerance limits for error. 3. Data Reduction Design Plan. This deals with analysis, presentation and use of the data. Calibration The relationship between the value measured and the system’s indicated output value is established by calibration. Calibration is the method of applying a known value of input to a measurement system for the purpose of observing the system output. The known value used for the calibration is called the standard. By application of a range of known values for the input and observation of the system output, a direct calibration curve can be developed for the measurement system. The accuracy of a system can be estimated during a calibration. The accuracy of a measurement system refers to its ability to indicate a true value, if the value can be known exactly. Absolute error is defined as the difference between the true value applied to the system and the indicated value of the system: = true value – indicated value Eq. 2-1 The percent accuracy is defined by 100||1truevalueA Eq. 2-2 The system’s accuracy is affected by both precision and bias error. The precision or repeatability of a measurement system refers to the ability of the system to indicate a particular value upon repeated but independent applications of a specific value of input. The precision error is a measure of the random variation found during repeated

PAGE 17

7 measurement. The bias error is the difference between the true value and the average of indicated values in a series of repeated calibration measurement. Presenting Data Data presentation conveys significant information about the relationship between variables. Software is readily available to assist in calculation as well as providing high-quality plots, such as rectangular coordinate, semilog coordinate and full-log coordinate. However, one disadvantage of those software packages is they frequently produce answers that appear to have much more accuracy than is warranted by the original input data [Fritschen & Gay, 1979]. This is a particular problem when data of varying degrees of refinement must be combined into analysis. Specific guidelines can be used when multiplying, dividing, adding or subtracting to eliminate those digits that carry no information. When adding or subtracting numbers, the answer should contain no more significant digits than are contained within the least accurate figure. When multiplying or dividing, the product or quotient should contain no more significant digits than are contained in the number with the fewest significant digits used in the multiplication or division. Fundamentals of Computer Control Systems Today almost all control systems are based on computer control [strm & Wittenmark, 1997]. Therefore it is important to understand it well. A computer control system can be described schematically as in Figure 2-2. The output from the process y(t) is an analog signal. The output is converted into digital form by the analog-to-digital (A/D) converter. The A/D converter can be included in the computer or regarded as a separate unit. The conversion is done at the sampling time t k . The computer processes the converted signal y(t k ) using an algorithm, and gives output u(t k ), which is then converted

PAGE 18

8 to an analog signal u(t) by a digital-to-analog (D/A) converter. The events are synchronized by the real time clock in the computer. Figure 2-2. Components of a Computer Control System A/D and D/A Converters Since computer systems work internally with numbers (digits), the electrical signals resulting from the sensors must be converted to digital data. This is done through an A/D converter, which is a device that samples an analog input voltage and encodes that voltage as a binary number. The necessity of converting analog signals to digital representation makes the A/D converter a common device in control applications. An A/D converter is usually specified with a full-scale voltage range E FSR and the number of bits of its register. For example, a typical 8-bit A/D converter with an E FSR = 10V would be able to represent analog voltages in the range of 0 to 10V with 2 8 = 256 different binary values. Principal considerations in selecting A/D converters include resolution, voltage and conversion speed. Primary sources of error intrinsic to any A/D converter are resolution and associated quantization error, saturation error and conversion error. A D/A converter uses a binary-number output to produce an analog voltage proportional to that number. It is commonly used when there are requirements for a computer control system to supply time-varying voltage outputs to actuators. Similar to Computer y(t k ) u(t k ) u(t) y(t) A/D Algorithm D/A Process Clock

PAGE 19

9 A/D converter, usually a D/A converter is also specified with E FSR and number of bits of register (M). Control Algorithm Many practical problems are solved by PID (proportional-integral-derivative) controllers. A PID controller can be described by the equation ))()(1)()(dttdeTdtteTteKtudI Eq. 2-3 in which e(t): error, the difference between the set-point and the measured variable u(t): controller output K: proportional gain T i : integration time T d : derivative time The primary parameters, K, T i , and T d , have to be chosen. Two classical methods can be used to determine the controller parameters, the step-response method and the ultimate-sensitivity method [strm & Wittenmark, 1997]. In the step-response method, the unit step response of the open-loop process is determined experimentally. The tangent to the step response that has the steepest slope (R) is drawn and the intersection of the tangent with the axes is determined, which is recorded as the apparent time L. The controller parameters are than obtained from Table 2-1 [strm & Wittenmark, 1997]. In the ultimate-sensitivity method, the controller is connected to the process and tested with only proportional control. The gain of the controller is then increased until the closed-loop reaches the stability limit. The gain (K u ) when this occurs and the period of the oscillation (T u ) are determined. The controller parameters are then given by Table 2-2 [strm & Wittenmark, 1997].

PAGE 20

10 Table 2-1. PID Parameters Obtained from the Step-response Method Controller Type K Ti T d P 1/a* PI 0.9/a 3L PID 1.2/a 2L 0.5L * a = RL Table 2-2. PID Parameters Obtained from the Ultimate-sensitivity Method Controller Type K Ti T d P 0.5K u PI 0.45K u T u /1.2 PID 0.6K u T u /1.2 T u /8 Control System Structure There are two basic arrangements of control systems, i.e., centralized vs. distributed. In a centralized system, the I/O accessories, the data acquisition and control device for interfacing with sensors and actuators, are all connected to the central computer directly. There are advantages to this method since sensitive electronic equipment can be removed from the open environment, which may not be a good place for instrumentation. The disadvantage is the necessity to run multiple cables from the central location to each controlled location, which increases the risk of electrical interference, damage to the lines and lighting strikes. In a distributed system, each location has its own microprocessor with limited memory capacity, keypad and display. Real time measurement and control are done inside the local processor. The central computer polls each local processor in succession, obtains the latest information, and calculates new set points if needed. If the central computer or one of the local processors fail, the reset local processor can still operate the system to a certain extent. The central computer and local processor can communicate through RS232 serial cable for distances less than 50m, or telephone line for distances beyond 50m.

PAGE 21

11 A good option of local processors are microcontrollers, which will be discussed in the next section. Microcontroller A microcontroller is a single chip computer [Yeralan & Emery, 2000]. It is usually composed of a processor, program and data memory, I/O ports, serial ports, timers, counters and interrupt logic. Without many extra components, it can interface to various peripherals such as motors, displays, sensors, communicate with PCs, and connect to a network of other similar controllers. This leads to compact and cost-effective systems, which have been widely used in everyday appliances such as washing machines, vacuum cleaners, microwave ovens, VCRs and etc. An average American home is likely to have only one or two general-purpose microprocessors but somewhere between one and two dozen microcontrollers. Microcontrollers come in a variety of sizes and complexities. Like microprocessors, microcontrollers can be classified as 8-bit, 32-bit or 62-bit systems. This refers to the width of the internal registers and the accumulator, and the data path that the CPU connects to various chip components. Controllers with larger data path can perform better than similar controllers with smaller data paths. But controllers with smaller data path have cheaper development tools [Gadre, 2001]. 8-bit microcontrollers are the most popular devices because of the lower cost for the devices themselves, as well as the lower cost for the development tools for them. The 8051 is the oldest microcontroller developed by Intel in late 70s. Over the years a complete family of microcontrollers has been developed based upon it, varying in sizes and types of memory and peripherals, such as more ports, A/D converters, and high-speed synchronous serial channels. Members of the family share the same basic elements

PAGE 22

12 and have the same basic group of instructions, which reduces the demands on software development. The 8051 family was created by Intel, but is now driven by many other companies, such as Atmel, Dallas Semiconductor, and Philips. Greenhouse Environment Control Designing a greenhouse environment control system requires knowledge of plant responses to the environment and the instruments used to measure and control environmental variables. Temperature Temperature effects The temperature range for plant growth is narrow, i.e., from about 10 C to 30 C. High temperature increases growth rates but reduces yields, while low temperature tends to increase yields but slow down growth rates. However, the relationship between plant growth and temperature is complex because it is a function of various metabolic processes. So an “optimum” temperature will vary with different objectives. Temperature measurement Temperature is the most common measurement made in greenhouses. Aside from its obvious effect on plant growth and development, temperature can be the basis for measurement of numerous other climatic values, such as humidity, radiation and CO 2 concentration [Hanan, 1998]. For example, the measurement of humidity often involves a determination of temperature to arrive at a value for the amount of water in air. The property of temperature can be inferred from a number of thermally induced physical attributes such as changes in volume and electrical resistance. For example, a liquid-in-glass thermometer measures temperature by the thermal expansion of a liquid. Table 2-3 listed three types of thermometers used in greenhouse.

PAGE 23

13 Table 2-3. Different Types of Thermometers Theory of Operation Example Uncertainty (C) Liquid-in-glass Thermal expansion Bimetallic .2 ~ RTD(conductor) Electrical resistance Thermistor (semiconductor) 0.005 Thermoelectric Thermocouple 0.2~ 2 The accuracy of temperature measurement is not only decided by sensor itself, but also influenced by the manner in which the measurement is made. Radiation, conduction, and convection can change the heat transfer on the equilibrium temperature of a temperature sensor. Following the rules listed below minimizes uncertainty in the resulting temperature measurement: 1) Any temperature sensor must be radiation shielded and aspirated. 2) The sensor must be located properly to the plant (e.g., plant surface temperature or plant air space temperature). 3) Data must be accumulated with regard to the change (time constant). 4) The properties of the sensor should be known, such as accuracy and response time. Temperature control Temperature control in a greenhouse includes heating, ventilation and cooling. There are four primary heating systems: steam, hot water, hot air and infrared. The first three may be used in combination. Infrared heating is not utilized on a wide basis due to a number of problems. To include natural ventilation is the principal and least expensive method used in greenhouses to prevent excessive heat. Evaporative cooling can be employed when natural ventilation is not sufficient, such as during summer when solar radiation is greatest.

PAGE 24

14 Humidity Humidity effects Humidity affects transpiration from plants by affecting the vapor pressure difference between a plant leaf and surrounding air. Normal plant growth will generally occur at relative humidity (RH) between 25-80%. Low RH will increase transpiration rate. High RH, on the other hand, will reduce the transpiration rate and may result in the growth of pathogenic organisms. Humidity measurement Knowledge of the basic definitions in common use is essential for understanding the principles of humidity measurement. Dry bulb temperature is the temperature measured by an ordinary thermometer. Wet bulb temperature is the lowest temperature to which an air mixture can be cooled solely by the addition of water. Dew point temperature is the temperature at which moisture starts to condense from air cooled at constant pressure and humidity ratio. Humidity ratio is the ratio of the mass of water vapor to the mass of dry air contained in the sample. Relative humidity is the ratio of the mole fraction of water vapor in a given moist air sample to the mole fraction in an air sample saturated at the same temperature. Absolute humidity (alternatively, water vapor density) is the ratio of the mass of water vapor to the total volume of the sample. There are several types of relative humidity measurement (Table 2-4). They vary in the theory of operation as well as output. Some of them, like aspirated psychrometer,

PAGE 25

15 gives the dry-bulb and wet-bulb temperature and need further calculation to get the value of relative humidity. Table 2-4. Different Types of Hygrometers Uncertainty Type of Hygrometer Theory of Operation Dew point (C) RH (%) Aspirated psychrometer Difference between dry-bulb and wet-bulb temperature 1 Human hair Hair elongation 3 3 Infrared Water vapor absorbs energy at certain wavelengths 0.5~3 Electrical absorption Resistance varies with humidity 1.5~ Dew point Dew point temperature 0.1 Humidity control A tight greenhouse is likely to have the problem of excessive humidity. However, humidity control can be difficult because the general behavior of humidity in a greenhouse is a function of whether a heating system is present, the type of heating and ventilation system, and the outside climatic conditions. The outside condition will often determine the methods and ability to control inside humidity. When outside humidity is lower than inside, humidity reduction can be accomplished with ventilation. In humid climates when outside humidity is higher, little can be done for humidity reduction without heating simultaneously with ventilation. In most climates in winter, dehumidification can also occur as a result of condensation on the roof and the outside wall surface.

PAGE 26

16 Radiation Photosynthesis and radiation Photosynthesis is the process through which radiation energy, water, and carbon dioxide are converted to carbohydrate and oxygen. The basic reaction of photosynthesis can be described with the following equation: 2222)(OOCHlightOHCOn Eq. 2-4 Intensity, duration, and spectral distribution of radiation will all affect plants’ development and growth. Figure 2-3. Photosynthetic Response to Wavelength Photosynthesis of higher green plants utilize light in the visible spectrum from 400 to 700 nm. Figure 2-3 shows that the rate of photosynthesis changes with wavelength [Koning, 1994]. All the wavelengths from 400-700 nm drive photosynthesis. Chlorophyll absorbs light in the longer wavelength length rangers, and arytenoids absorb in the shorter wavelength ranges. However, there is a drop in effectiveness at 540 nm, corresponding to green light. Obviously plants use less of this light and reflect more of this color to our eyes, and that is why plants look green. Wavelengths outside the range of

PAGE 27

17 the graph shorter than 400 nm can drive photosynthesis in some cases. However, wavelengths longer than 700 nm appear to be unable to drive photosynthesis. Plant response to light intensity varies with different species. C 3 plants are characterized by relatively low rates of CO 2 at saturating irradiances, as contrasted to C 4 species that may have photosynthetic rates double that of many C 3 s. Most species grown commercially in greenhouses are C 3 plants. C 4 species are most often found among the tropical and temperate warm weather grasses and sedges. Net photosynthetic rates per unit leaf mass and area of a C 3 plant can be described with a Michaelis-Menten model: PFDPFDmazRPFDkPFDAPFDA )( Eq. 2-5 where PFDA( ) = CO 2 uptake rate (mol CO 2 /m 2 /s) A max = maximum CO 2 assimilation rate (mol CO 2 /m 2 /s) k PFD = Michaelis-Menten constant (mol photon/m 2 /s) R PFD = dark respiration rate (mol CO 2 /m 2 /s) PFD = photosynthetic photon flux density (mol photon/m 2 /s) Figure 2-4 [Givinish et al., 2004] shows photosynthetic rate (amount of carbon dioxide used to make carbohydrate per second) vs. incident light flux. The net carbon uptake rate converges on (A max R) at high PFD, rising from -R (dark respiration) at zero PFD and traversing half the potential range in net uptake by a PFD of k. Note that A max is substantially above the actual maximum net photosynthetic rate. The light instantaneous compensation point (ICP) is achieved where A(PFD) = 0, that is, at the photon flux density at which the light-response curve crosses the x-axis. This happens due to the interaction between respiration and photosynthesis. The dark Respiration rate, R, which is not a light-driven pathway, does not change with PFD, while photosynthesis increases

PAGE 28

18 with increasing light intensity. At the compensation point, the respiration and photosynthesis rates equal and thus compensate for each other, and the plant is "breaking even" in terms of producing carbohydrate and using it. Figure 2-4. Schematic Diagram of Michaelis-Menten Photosynthetic Light Response Some plants also respond to the relative length of day and night, and are termed photoperiodic. Photoperiodism affects flowering and photoperiodism responses can be induced at relatively low light levels. Depending on their responses to the duration of light, plants can be grouped as long day, short day, or day neutral, with the length of darkness being more important than the length of the light period. Radiation measurement Instrumentation for measuring radiation can be separated into three classes: radiometers, photometers, and quantum meters. Glass-covered radiometers, such as Eppley, convert radiant energy to heat. With glass domes, the spectrum measured is from 300 to about 3000nm. Photometers are made to provide a response similar to the human

PAGE 29

19 eye. They do not detect radiant energy above or below the visible light. Quantum meters are constructed to measure the Photosynthetic Active Radiation (PAR), which is the radiation equally over the band 400 to 700nm, and which is actually measured as total PFD across the wavelength band. Common measurement of solar radiation in the field usually has errors of %, using the standard Eppley. The measurement accuracy of most common quantum instruments appears to be %. A problem with most radiation sensors is their small response surfaces that make them very susceptible to shadows from the greenhouse superstructure. However, shadows move as the sun tracks across the sky. Radiation (PFD) control Radiation control includes supplementing solar energy with artificial light and reducing solar energy with shading. Several types of lamps are available, among which fluorescent lighting has been found most useful for seedling germination and initial growth. Mercury and metal halide lamps are among those first used for high-intensity supplemental irradiation. Their efficiency makes them cost effective. More recently, high-pressure sodium lamps have come into increasing use. The yellow light from these lamps may not be desirable where appearance is important. To reduce solar energy, almost any kind of material can be used as shading, ranging from cheese cloth to woven plastic screen and metallic woven cloth. Attempts have been made to use flowing water or colored solutions over the greenhouse roof. One thing should be noticed with this kind of screen is that it should reject the sun’s infrared rather than the visible or PAR. Radiation control may also include the control of flowering through manipulation of day-length.

PAGE 30

20 CO 2 Photosynthesis and CO 2 Photosynthetic rates respond to increasing levels of CO 2 but then level off at higher concentrations (around 700 ppm or greater, depending upon species and other factors, such as acclimation to high PFD). Similar to light, the response also varies with different species. C 3 s have higher CO 2 compensation points, which are when the external CO 2 concentration exactly equals the leaf intercellular CO 2 level provided by the respiratory process. The photosynthetic rates are relatively low in C 3 s at saturating CO 2 compared to C 4 s. A Michaelis-Menten type of rectangular hyperbola equation can be used to summarize photosynthetic responses of C 3 plant to CO 2 concentration. ][][][][])([CCmazRCkCACA Eq. 2-6 where A = CO 2 uptake rate (mol CO 2 /m 2 /s) A max = maximum assimilation rate (mol CO 2 /m 2 /s) k [C] = Michaelis-Menten constant (ppm) R [C] = dark respiration rate (mol/m 2 /s) [C] = CO 2 concentration (ppm) CO 2 measurement There are numerous methods for measuring CO 2 , including chemical absorption, thermal conductivity, infrared spectroscopy, gas chromatography, and electrical conductivity. But the principal process now used is infrared spectroscopy or infrared gas analyzers (IRGAs), which are sensitive to the number of CO 2 molecules per unit volume or pressure in the path length of an IR beam. . They can be used directly with control devices and be interfaced with computers.

PAGE 31

21 CO 2 enrichment Higher levels of CO 2 are beneficial to plant growth. The current atmosphere contains 370ppm of CO 2 , which is much lower than the optimum CO 2 level for most plants. Additional CO 2 is often provided to the greenhouse to maintain levels of 1000~1500ppm. There are two main CO 2 sources for greenhouses, pure gas and that produced by fuel combustion, usually methane or propane. Pure CO 2 gas is the most expensive source, but also the safest and most easily controlled. Fuel combustion is cheap compared with pure CO 2 and can also supply heat simultaneously. However, it has disadvantages when no heat is required. It can also cause damage and contamination if the fuel is burned inside. CO 2 supplementation can be accomplished simply by injecting pure CO 2 at a constant rate or burning the appropriate fuel quantities when the greenhouse is closed. This is a simple and cheap procedure requiring no fancy equipment. However, it may cause oversupply of CO 2 in dark weather, or limitations to the period when the greenhouse is closed. More suitable analytical equipment can be utilized in combination with a climate-control computer. This approach, although more expensive, can save CO 2 cost, prevent crop damage as the result of CO 2 excess, and improve net return to the operation. Low Pressure Plant Growth Studies Most LPPG studies have been focused on the limit of the lowest pressure that plants can survive, the effects of light, total pressure, ppCO 2 and ppO 2 on photosynthesis, transpiration and dark respiration. Lately, studies on plant germination and reproduction have also been performed.

PAGE 32

22 Research on the possibility of growing plants under low pressure goes back to as early as 1960s, when NASA began considering the use of plants for life support of long-duration space missions. One of the earliest tests at Brooks Air Force Base showed slight enhancements in percent dry matter of seedlings at 51 and 93kPa total pressure. Several years later, work at Wright-Patterson Air Force Base demonstrated that pressures as low as 1/3 atmosphere may not lead to adverse effect on plant vegetative growth. Studies at KSC have dropped this limit even lower, and showed that lettuce was able to tolerate pressures as low as 10 kPa or slightly lower, provided that high moisture in the root zone and high humidity in the atmosphere are maintained [Corey et al., 2002]. The lowest pressure ever reached in a plant study, was 7 kPa. It was obtained by evacuating the chamber and adding oxygen. Results showed that germination and growth were possible under that low pressure, if proper CO 2 and O 2 were supplied. Plant responses to reduced pressure are still uncertain, although it has been reported in several studies that reduced pressure enhances the rates of CO 2 uptake and transpiration. When changing air pressure, diffusion in the gas phase is not affected since the diffusion coefficient is inversely proportional to total pressure. However, pressure does affect diffusion in the liquid phase of cells and tissues. Diffusion in the liquid phase is dependent on the concentration of dissolved gas, which in solution is determined by the partial pressure. Thus, the primary effects on photosynthetic or respiratory gas exchange should be limited and be governed by the extent to which liquid phase diffusion is involved. Pronounced primary effects have to be expected on transpiration, because the vapor pressure within the stomates remains unchanged so that a raised diffusion coefficient leads to enhanced vapor transfer into the ambient air. For growth as a long

PAGE 33

23 term process, secondary effects could be even more important, e.g. as a consequence of enhanced water and mineral intake, changes in initiation and expansion of new leaves with concomitant changes in morphology and light interception or adaptation to the photosynthetic apparatus to reduced CO 2 concentration within the chloroplast [Daunicht & Brinkjans, 1996]. Gale tested the idea of possible enhancements of transpiration rates under low pressure with corn and bean [Corey et al., 2002]. Experiments confirmed this prediction. At the Kennedy Space Center (KSC), experiments with lettuce showed that reduced pressure resulted in an increased rate of water loss compared to water loss at ambient pressure (101kPa). Water loss was found to be inversely correlated with atmospheric pressure over the range from 21 to 101 kPa. However, increased transpiration in this study may have been caused by low relative humidity. Further study is needed to be done with separate control of total pressure and relative humidity. Enhancement of CO 2 uptake rate also has been reported in most studies [Ohta et al., 1993; Goto et al., 1995, 1996; Corey et al., 1995, 1997;] However, Daunicht’s research with tomato plants [Daunicht & Brinkjans, 1996] found that the photosynthetic rate under 40kPa was lower than 70kPa, probably due to secondary air pressure effects. He [He, et al., 2004] at Texas A&M also found that the CO 2 uptake rate of lettuce was lower at 70kPa than at 100kPa. Whether this disagreement was actually the difference between plant responses, or was caused by control or measurement insufficiency is still uncertain. The most commonly observed effects of increased CO 2 are increased photosynthesis and reduced photorespiration, which, however, does not indicate that higher CO 2 is always better. Wheeler studied the effect of high ppCO 2 on plant growth in order to find out whether CO 2 can be used as the pressuring gas for a Mars greenhouse,

PAGE 34

24 since there is plenty of CO 2 on Mars. Results showed that high ppCO 2 (>0.5 kPa) might become injurious and /or increase water demands in some species [Wheeler, 2000]. Wheeler concluded that further studies are needed to define these CO 2 responses. If reduced pressure is also accompanied by reduced ppO 2 , net photosynthesis and growth may occur through a reduction in carbon loss by suppression of photorespiration, as well as the reduction of ethylene synthesis. Musgrave found enhanced growth of mungbean at pressures of 21-24 kPa and enhanced growth at low oxygen (5kPa) and reduced pressure compared with low oxygen and ambient pressure [Corey et al., 2002]. ppO 2 , rather than the total pressure, may also be the primary factor controlling CO 2 uptake and seedling growth. Corey found that when the ppO 2 was held constant but the total pressure was varied between 51 and 101 kPa, the rate of CO 2 uptake was nearly constant [Corey et al., 1996]. Germination of wheat seed was found to be completely inhibited over a pressure range of 1-101kPa. However, when 5kPa supplemental O 2 was provided to a 6kPa total pressure atmosphere, germination was not significantly different from the control [Schartzkopf & Mancinelli, 1991]. Seed production of Arabidopsis at 23 kPa total pressure with 21kPa of O 2 was almost the same as at atmospheric pressure [Arai et al., 2003]. Goto also conducted experiments to study the germination of rice and Arabidopsis under different total pressure and ppO 2 [Goto et al., 2002]. Results showed the different responses of these two kinds of plants. For rice, germination was highest at the highest ppO 2 of each total pressure, which was probably because the lower oxygen concentration inhibited respiratory activity. On the other hand, lower total pressures showed higher percentage germination at a similar ppO 2 . The higher O 2 concentrations may be

PAGE 35

25 maintained inside seeds by higher O 2 gas diffusion under hypobaric conditions, which in turn maintained respiratory activity at a suitable level. For Arabidopsis, in contrast to rice, low pressure did not enhance germination. Also there is a lower limit of total pressure around 25 kPa for Arabidopsis germination. Seeds could not germinate at 10kPa. The above research showed not only the possibility of growing plants at low pressure, but enhanced growth and development with optimization of gas compositions (total pressure, CO 2 , O 2 and H 2 O). However, further studies need to be done with separate control of total pressure, ppO 2 , ppCO 2 and RH to study the individual as well as combine effects on plant growth from seed germination to seed harvest. Instrumentation for Low Pressure Plant Growth Chamber Major aspects of instrumentation for LPPG chamber are: 1) system design; 2) selection of instruments, including sensors, control equipment, tubing and fitting; 3) leakage reduction; 4) sensor calibration 5) control algorithm design. Some instruments are affected by low pressure, such as O 2 and CO 2 sensors, and have to be calibrated under low pressures. These issues were discussed in almost all papers published about low pressure plants growth studies. At Kennedy Space Center, a chamber with high vacuum capability was set up for testing plant responses to reduced pressure atmospheres. A test rack with lighting provided by three high-pressure sodium vapor lamps was built to conduct measurements of short-term plant responses. Temperature and relative humidity were controlled by the Atmospheric Tower Management System (ATMS) consisting of air heater and cooling coils [Fowler et al., 2001]. Water requirements were determined by the use of scales under each plant. The weight was monitored, and the irrigation system was activated when a deficit was reached. Lettuce was grown successfully under 25kPa in this chamber

PAGE 36

26 for about 30 days. However, relative humidity control was not satisfactory, especially when both temperature and RH were considered. Several approaches were tried to address this problem, such as adding an impeller humidifier and a water barrier, but they were either not able to provide enough humidity or caused a lot of condensation. There was not much gas mixture control except adding CO 2 periodically. Several humidity sensors, Vaisala HMI 41 Humidity and temperature indicator (capacitance type), Edgetech Vigilant hygrometer (chilled mirror type), LI-COR 6252 (infrared type), and the basic wet/dry bulb type systems, were tested under low pressure and their outputs were recorded. All of them tracked close to each other except the infrared detector, which tended to read lower at lower pressures. The infrared detector read lower because of pressure broadening which worked in severe when pressures were lowered. From this test, a conclusion was made that pressure did not adversely affect the ability of the sensors to detect humidity levels. However, sensors were not calibrated against any standard. Calibration of CO 2 and O 2 sensors, which were known to be affected by low pressure, was not mentioned. A research group in Tokyo, Japan, led by Goto, has been using an environmental control system to study plant growth under hypobaric conditions that operated at pressure down to 10kPa. The system achieved complete control of total and partial pressures of N 2 , O 2 and CO 2 levels, which were regulated by repeating the following routine [Iwabuchi et al., 1996]. First, the vacuum pump exhausted the air inside the growth chamber to reduce the total pressure, and the exhausted air was compressed to atmospheric level and measured by the O 2 analyzer. ppCO 2 and ppO 2 within the growth chamber were calculated by the measured values. Next, by running the vacuum pump, N 2

PAGE 37

27 and O 2 gases, mixed to a proper ratio in the mixing box, were supplied to the chamber through the pressure regulator. The pressure regulator controlled the amount of gas supplied to the growth chamber and maintained the total pressure inside the chamber at the set level. CO 2 gas was directly injected to the chamber whenever ppCO 2 inside the growth chamber fell lower than the set point. After the ppCO 2 and ppO 2 inside the chamber reached the set points, the gas supply and exhaust were stopped and the chamber was entirely closed for several minutes. After closing the growth chamber, the routine was repeated. The amount of time the growth chamber was closed was adjusted to the plant size so that the ppCO 2 decrease during the routine was less than 11Pa. This control algorithm worked fine, however, using another gas mixing box may introduce more leakage, and evacuating the chamber periodically left the system under real vacuum for a short time once in a while, and whether this has any effect on plants ha not been determined. The CO 2 and O 2 sensors used could not work under low pressure, so the air had to be compressed before the correct reading could be obtained from the sensors. The RH sensor (THT-B5AT, Shinyei Kaisha) was claimed to be designed especially for low pressure, but no verification was described. The calibration of sensors was not described either. In Texas A&M University, a distributed control system was developed for LPPG chambers, using microcontrollers, a personal computer (PC), and a process gas chromatograph [Brown & Lacey, 2002]. A PC collected data from the microcontrollers and returned setpoints for total pressure, CO 2 , O 2 , and N 2 concentration. The gas composition was monitored by a process gas chromatograph, which delivered data to the PC via the MODBUS protocol. Temperature and lighting were controlled by putting the

PAGE 38

28 six LPPGs into a plant growth room. Gas mixture was controlled by microcontrollers according to a “Pivot Gas” algorithm, which should be able to adjust total pressure and partial pressures separately. However, the algorithm could result in large amounts of gas added to the chamber, sometimes raising pressure inside the chambers to two or three times atmospheric pressure. Also the program was too big for the limited program space on the MCUs, and had to be moved to the PC. At the same time, values of gas mixture had to be obtained through communicating with the PC instead of directly from sensors. The LPPG had a low leak rate of 2 to 5% of total volume per day at a total pressure of 5kPa, which was much better than the original 32% leakage. But there was not much detailed description about how the leakage was reduced. The chambers that Daunicht and Brinkjans used were open systems in that the chambers were ventilated by a constant flow of atmospheric air [Daunicht & Brinkjans, 1996]. Ventilation and air pressure were integrally controlled by a combination of mass flow controller, mechanical precision vacuum controller, and vacuum pump. This arrangement turned out quite well. It allowed CO 2 analysis at ambient pressure (sample air from the outlet of the vacuum pump), maintained O 2 as constant as found in the atmosphere, and excluded gas contaminant accumulation within the chambers. The plant volatiles chamber used by Corey was controlled by an 80286-based PC, which was outdated even at that time. Pressure was adjusted manually through the vacuum pump and a bleed valve. The variable pressure growth chamber (VPGC) in Johnson Space Center, has a leakage rate of 1.16 volumes/day that required extra tests and compensation equations to determine accurate gas exchange rates.

PAGE 39

29 From this review it can be seen that although several test facilities have been used to study plant responses to reduced pressure, most of them either have limitations or are not well documented, which makes reproduction difficult. There is a definite need for a systematic approach to set up a low pressure plant growth system, and fully document everything so that later, other researchers can have a good reference.

PAGE 40

CHAPTER 3 OBJECTIVES The objective of this study is to come up with a systematic approach to simplify the procedure of setting up a Low Pressure Plant Growth (LPPG) chamber and developing a control system for the chamber The steps to achieve the objective are: 1) Set up the LPPG chamber a. The chamber should be able to withstand certain amount of external pressure without significant leakage. b. All the hardware, including sensors and control equipment, should work under low pressure. 2) Design a control system for the LPPG chamber a. Use modular design so that the system can be easily adapted to meet other research requirements. b. The system should be able to control total pressure, ppCO 2 , ppO 2 and RH. c. Software for the microcontroller should do the real time data collection and control, as well as handling commands from PC. d. Software for the PC should have a user friendly interface, store data in a database, and communicate with the microcontroller. 3) Plant tests The system should be able to provide different conditions that plant test needs. 4) Develop a systematic approach to set up a LPPG chamber 30

PAGE 41

31 Based on the research experience, come up with a systematic approach to simplify the procedure of setting up a LPPG chamber, which will act as a guide or reference for people who will do similar research later.

PAGE 42

CHAPTER 4 MATERIALS AND METHODS System Description The low pressure plant growth system was composed of a plant growth chamber, gas supply tanks, sensors and controls, a microcontroller and a PC, as seen in Figure 4-1. The plant growth chamber was a glass Pyrex bell jar. The body was 38cm in height, 21cm in inner diameter and about 3mm in thickness. The bottom sat on a 7mm-thick aluminum plate. To minimize the chamber leakage, a gasket was placed between the bell jar and the plate, and vacuum grease was also applied between the bell jar and the gasket. Six 3.2mm holes and two 6.4mm holes were made in the aluminum base. The 3.2mm holes were used as inlets for gases and water, while the 6.4mm holes were for wire feed-throughs used to provide power supply and to monitor output of the sensors in the chamber. Plastic tubing was used for water and gases. Plastic, stainless steel and copper tubing were tested before the plastic tubing was finally chosen, balancing between the ability to hold vacuum as well as the difficulty in handling. The gas supply system was composed of three lines for N 2 , CO 2 and O 2 . Each line had a gas bottle, a pressure regulator and a mass flow controller. For temperature and light control, everything except the PC was put into a larger (2.7m1.8m.4m) walk-in environmental growth chamber with two 400W metal halide lamps (GC series, EGC company), where temperature, lighting intensity and period were controlled. The plant pot was put on a scale. A tube with a valve, which was normally closed, brought water to the pot from an outside water supply. The pot was periodically 32

PAGE 43

33 measured, and whenever a deficiency of water was indicated, the valve opened, and the pressure difference between inside and outside would supply water to the pot. N 2 CO 2 O 2 Light Vacuum Pump scale MFC MFC MFC Dehumidifier Bell jar Growth Chamber Water Su pp l y Temp RH PressuCO 2 O 2 Figure 4-1. Setup of the Experiment Temperature, RH, light, pressure, CO 2 and O 2 were monitored. Sensors are listed in Table 4-1. Temperature was measured with a digital thermometer (DS18B20, Dallas Semiconductor), which provided 9-12 bits digital readings of Celsius. It had an operating range of C to 125C with an accuracy of .5C over the range of C to +85C. It communicated over a 1-wire bus that required only one data line and ground for communication with the microcontroller. In addition, it could derive power directly from the data line, eliminating the need for external power supply. RH was measured by a thermoset polymer capacitive RH sensor with on-chip integrated signal conditioning (HIH-3602-L, Honeywell, Sensing and Control). An absolute pressure sensor (ASCX15AN, Sensym ICT), which gave out 0-5V output over the range of 0-15psi with an accuracy of .5%, was put inside the bell jar to measure the pressure. Two CO 2

PAGE 44

34 sensors were used for different ranges of CO 2 concentration, which were GMM 220 for 0-10% of CO 2 and GMM221 for 0-5000ppm of CO 2 . Both of them were infrared type sensors from VAISALA company. A Galvanic cell O 2 sensor (Max250, MaxTec) was used for O 2 monitoring. Light was monitored with quantum sensor (LI-190SA, LI-COR Inc.). Table 4-1. Sensors Parameters Type Power Supply Output Operation Range Accuracy Temperature DS18B20 digital thermometer (Dallas Semiconductor) 5 V 9-12 bits centigrade temperature -10-85 C 0.5 C RH HIH-3602-L capacitance type RH sensor (Honeywell) 5 V 0-5V 0-100% % Light LI-190SA quantum sensor (LI-COR Inc.) No 8a/1000 mo l s -1 m -2 0-10,000 mol/m 2 /s % Pressure ASCX15AN (Sensym ICT) 5V 0-5V 0-15 psi 0.5% GMM 221 (VAISALA) 12V 0-5V 0-10% 0.02% CO 2 GMM222 (VAISALA) 12V 0-5V 0-5000ppm 20ppm O 2 Max 250 (MaxTec) No 0-65mV 0-100% 2%FS* Mass Flow M100B (MKS) V 0-5V 10, 100, 500, 1000sccm %FS* *FS: full scale range The system was designed to be airtight to minimize the leakage. But on the other hand, the airtightness, plus the enhanced plant transpiration under low pressure, caused a rapid increase in RH. Therefore, the system needed a dehumidifier with higher performance to maintain RH at the desired level for plant growth. A thermoelectric unit, plus a fan and a heat sink were combined into a dehumidifier. The cold side of the thermoelectric unit was attached to a heat sink. The fan forced the air to circulate through the cold surface of the heat sink, causing water to condense on it. The hot side of the

PAGE 45

35 thermoelectric unit was put on the bottom of the aluminum plate, which, combined with a fan attached to it, acted as a heat exchanger to transfer heat out to the ambient air. To collect the condensed water, the heat sink was covered with a very thin layer of wick material and the other end of the wick extended up to the pot. In this way condensed water would be transferred back to the pot through strong capillary action. However, it was later found out that the distance between the pot and the heat sink (25cm) was beyond the ability of most wick material available on the market. So another plan was used. The sides and bottom of the heat sink were wrapped with aluminum. In this way, the heat sink was turned into a small container for temporary water storage. Then a layer of insulation was added to the sides of the heat sink to prevent free water from condensing on it. Leakage Reduction Leakage caused by the difference between inside and outside pressure was always a problem of a LPPG chamber, because it affected the accuracy of gas measurement and control. The leakage rate at the beginning of the project was greater than 300% volume per day. Gases outside entered the bell jar through its bottom edge and all the fittings and tubing for gas and fluid transfer. Leakage from the bell jar bottom edge was fixed with a rubber gasket between the bell jar and the base plate, plus the vacuum grease applied on both of them. The fittings and tubing, although vacuum rated, could still cause leakage due to improper assembly. In order to detect those kinds of leakages, helium tests were applied on each individual piece of tubing. The tubing was totally sealed with only one open end connected to a helium gas tank. Then each connection on the tubing was put into water. If there was leakage, it would make bubbles in the water. Leakage in several fittings and tubing were detected in this way. After they were fixed or replaced, the

PAGE 46

36 leakage rate was reduced to less than 5% per day at pressure of 25kPa. One note about the helium test was, it did not guarantee detection of all the leakages because during the test, the helium gas inside the tubing had a higher pressure than the outside, which actually helped sealing the tubing and fittings; when the tubing was connected to the bell jar, it was the other way round. The outside pressure was greater than the inside, which increased the chance of leakage. Sensor Calibration Preliminary Tests One of the unknowns at the start of the project was whether the instrumentation would work at low pressure. Certain types of instruments were unaffected by low pressure such as temperature and pressure sensors, while others such as humidity, CO 2 and O 2 sensors could be sensitive. Some preliminary tests were done to check the sensor responses at low pressure. RH sensor Theoretically, since the saturated vapor pressure is only a function of temperature, if temperature is kept constant, then the water vapor saturation pressure will be constant as well. And if the total pressure inside the bell jar is reduced by pumping air out, the RH should be proportional to the total pressure, as seen below, pTppRHwsW, Eq. 4-1 wWpp )(Tppwsws In which RH: relative humidity p w : partial pressure of water vapor

PAGE 47

37 p: total pressure p ws : water vapor saturation pressure, which is a function of temperature : mole fraction of water vapor T: temperature The readings obtained from the RH sensor at different pressures were proportional to the pressure, as seen in Figure 4-2, which agreed with the theory, so it could be assumed that the RH sensor worked fine under low pressures. y = 0.4655x + 9.7663R2 = 0.9965y = 0.4607x + 11.799R2 = 0.99401020304050607080901000102030405060708090100P (kPa)RH (%) Figure 4-2. RH vs. Pressure CO 2 sensor When pumping air out of the bell jar, since all gases are pumped out at same speed, the CO 2 concentration should remain the same, and ideally the sensor reading should not change. However, the readings obtained from CO 2 did not remain constant, which indicated that CO 2 sensor was sensitive to total pressure. On the other hand, the readings were proportional to the total pressure, which indicated that the CO 2 sensor could be used under low total pressure after being calibrated under different total pressures.

PAGE 48

38 y = 4.4719x + 18.978R2 = 0.9982050100150200250300350400450500020406080100120P (kPa)CO2 Figure 4-3. CO 2 vs. Pressure O 2 sensor O 2 sensor response was similar to the CO 2 sensor’s, with the only difference being the linear function of pressure may be different with different pressure ranges. 0501001502002503003504004505000102030405060708090100110P (kPa)O2 Figure 4-4. O 2 vs. Pressure After the preliminary tests, CO 2 and O 2 sensors were then calibrated under different pressures, which will be discussed in the following section.

PAGE 49

39 Calibration Procedure Two different CO 2 sensors (GMM 221 and GMM222) were used in this project for different CO 2 concentration ranges. The GMM221 was used for 0-10% of CO 2 and GMM 222 for 0-5000ppm. A slightly different procedure was designed for each of them. The first difference was the calibration standard. In this case, this standard should be a gas mixture with known concentrations of CO 2 and O 2 . Commercial gas mixtures were available, but were prohibitively expensive. So instead, gas mixtures were produced with mass flow controllers, whose accuracy were about 2%. But since leakage, control and instrument accuracy would all influence the final gas mixture, the gas mixture was also measured with a gas chromatograph (GC), which had an accuracy of 2%, and used as the standard for GMM221. For GMM222, the sensor itself was used as the standard, because the GC used was found to work only for concentrations above 0.5%, and also because the sensor was already calibrated by the manufacturer and its reading could be trusted under normal atmosphere pressure. The second difference was in the way gases were mixed. For 0-10 %, N 2 , O 2 and CO 2 flowed into the chamber through MFCs at the same time, with the control voltage MFC being setup according to the gas mixture required. For 0-5000ppm, the chamber was filled with O 2 and N 2 first, and then CO 2 was added to the set concentration, because the ppCO 2 would be less than 0.5 kPa and would not influence the total pressure and the ppO 2 . Figure 4-5 shows the setup of the calibration. Sensors were put inside the closed ball jar. Gases were supplied into the chamber with mass flow controllers. A syringe was used to take out gas samples for GC analysis.

PAGE 50

40 CO 2 Sensor O 2 Sensor WireFeedthrough Power Supply Micro-controller N 2 CO 2 MFC MFC MFC Vacuum Pump Syringe to take O 2 Figure 4-5. Setup of the Sensor Calibration Here are the calibration steps for GMM221 (similar steps for O 2 sensor): 1. Evacuated the bell jar until pressure dropped lower than 5kPa. Then turned on the Mass Flow Controllers (MFC) for CO 2 , O 2 and N 2 , while at the same time kept on pumping for a few minutes, to purge out the residue gases. 2. Shut the pump off and let the gas flow fill the bell jar. Waited until the total pressure reached 100kPa. 3. Took a sample with a syringe. The size of the sample should be greater than 45ml. 4. Pumped down to 50kPa, held for one minute, and got sensor reading from the microcontroller. 30 readings were taken and the average was used as the final data. Repeat this for 40, 30, 20 and 10kPa. 5. Analyzed the samples with the GC. Each sample was injected into the GC in three separate times to produce three repetitions. The average of the three readings was used as the GC data. Here are the steps for GMM222: 1. Evacuated the bell jar until pressure dropped lower than 5kPa. Filled it with N 2 until it got to 100 kPa, then pumped it down again to lower than 5kPa. In this way the residue CO 2 from the previous gases was less than 0.025%. 2. Shut the pump off. Added O 2 and N 2 (O2:N2 =1:2) until the pressure reached 100kPa.

PAGE 51

41 3. Add CO 2 to reach the set point. For example, if CO 2 = 5000ppm, then add CO 2 until total pressure equals 100.5kPa 4. Wait until the reading get stable, then record the sensor reading 5. Pump down to 50kPa, hold for one minute, and get sensor reading from the microcontroller. 30 readings were taken and the average was used as the final data. Repeat this for 40, 30, 20, 10 and 5kPa. Data were recorded and analyzed. Half of the data were used for sensor calibration, while the other half was used for verification of the calibration equation. CO 2 sensor (GMM 221) Table 4-2 shows the CO 2 sensor (GMM221) reading at different pressures and CO 2 concentrations. The CO 2 concentrations were the results from GC. Table 4-2. GMM221 CO 2 Sensor Reading P(kPa) CO 2 (%) 50 40 30 20 10 5 2.1 5506.7 4202.2 3078.8 2080.8 1148.2 693.3 1.0 3142.8 2544.6 1961.1 1367.8 816.5 511.1 3.4 7692 5719 4108 2825 1539 833.6 Plot the CO 2 reading vs. CO 2 %, as in Figure 4-6. It can be seen that for a certain pressure, the sensor output was linear with respect to the CO 2 percentage. Which means that CO 2 sensor output was a function of the pressure and CO 2 percentage, and the function had a form like: )(%)(Re22PgCOPfadCO Eq.4-2 in which CO 2 Read: reading from CO 2 sensor CO 2 %: CO 2 percentage P: pressure (kPa)

PAGE 52

42 y = 1912.8x + 1317.8R2 = 0.9913y = 1334.4x + 1274.5R2 = 0.9907y = 902.62x + 1100.7R2 = 0.9911y = 614.22x + 765.16R2 = 0.9966y = 305.3x + 508.8R2 = 0.9994y = 135.1x + 387.65R2 = 0.9789010002000300040005000600070008000900001234CO2 %CO2 Reading 50 kPa 40 kPa 30 kPa 20 kPa 10 kPa 5 kPa Linear (50 kPa) Linear (40 kPa) Linear (30 kPa) Linear (20 kPa) Linear (10 kPa) Linear (5 kPa) Figure 4-6. CO 2 Reading vs. CO 2 % In order to get the function of f(P) and g(P), first the slope and intercept of each line were listed in a table, as in Table 4-3. Then the slope and intercept vs. P were plotted, as in Figure 4-7. From Figure 4-7, 69.166352.39)( PPf Eq.4-3 19.355273.21)( PPg Eq.4-4 Substituting Eq.4-3 and Eq.4-4 into Eq.4-2, gave 19.355273.21%)9.166352.39(Re22 PCOPadCO Eq.4-5 Rearranging Eq. 4-5 gave 69.166352.3919.355273.21Re%22PPadCOCO Eq.4-6

PAGE 53

43 Table 4-3. Slope and Intercept for Each Line P (kPa) 50 40 30 20 10 slope 1912.8 1334.4 902.6 614.2 305.3 intecept 1317.8 1274.5 1100.7 765.16 508.8 y = 39.352x 166.69R2 = 0.977y = 21.273x + 355.19R2 = 0.9376050010001500200025000102030405060P (kPa)Slope and Intercept slope intecept Linear(slope) Linear(intecept) Figure 4-7. Slope and Intercept vs. Pressure CO 2 sensor (GMM 222) Table 4-4 is the CO 2 sensor reading at different pressures and CO 2 concentrations. Table 4-4. GMM222 CO 2 Sensor Reading P(kPa) CO 2 ppm 50 40 30 20 10 5 420.2 1844.4 1628.1 1443.5 1156.5 797.6 590.2 934.0 3048.4 2597.4 2062.9 1495.7 913.5 655.3 2279.4 3048.4 2597.4 2062.9 1495.7 913.5 655.3 3632.8 9257.2 7247.8 5386.5 3666.57 1981.0 1220.4 The CO 2 reading vs. P were plotted, as in Figure 4-8.

PAGE 54

44 y = 27.908x + 526.97R2 = 0.9803y = 178.41x + 185.2R2 = 0.9982y = 115.79x + 420.35R2 = 0.9992y = 54.47x + 392.06R2 = 0.99810100020003000400050006000700080009000100000102030405060P (kPa)CO2 420 ppm 938ppm 2279ppm 3632ppm Linear (420 ppm) Linear (3632ppm) Linear (2279ppm) Linear (938ppm) Figure 4-8. CO 2 Reading vs. Pressure For a certain CO 2 concentration , the sensor output was linear with respect to the total pressure, which meant CO 2 sensor output was a function of the pressure and CO 2 concentration, and the function has a form like: )()(Re222ppmCOgPppmCOfadCO Eq.4-7 in which, CO 2 Read: reading from CO 2 sensor CO 2 ppm: CO 2 concentration in ppm P: pressure (kPa) In order to get the function of f(CO 2 ppm) and g(CO 2 ppm), first the slope and intercept of each line were listed in a table, as Table 4-5. Table 4-5. Slope and Intercept for Each Line CO 2 (ppm) 420.2 938.0 2279.4 3632.8 slope 25.9 54.1 116.8 181.9 intercept 600.7 405.3 383.5 54.0

PAGE 55

45 The slope and intercept vs. CO 2 (ppm) were plotted, as in Figure 4-9 and Figure 4-10. y = 0.0466x + 9.4794R2 = 0.999802040608010012014016018020001000200030004000CO2 (ppm)Slope Figure 4-9. Slope vs. CO 2 ppm y = -0.0884x + 541.77R2 = 0.794010020030040050060001000200030004000CO2 (ppm)Intercept Figure 4-10. Intercept vs. CO 2 ppm From Figure 4-10, 4794.90466.0)(22 COppmCOf Eq.4-8 77.5410884.0)(22 ppmCOppmCOg Eq.4-9 Putting Eq.4-8 and Eq.4-9 into Eq.4-7, gave

PAGE 56

46 77.5410884.0)4794.90466.0(Re222 ppmCOPppmCOadCO Eq.4-10 Rearranging Eq.4-10 gave 0887.00466.077.5414794.9Re22PPadCOppmCO Eq.4-11 Table 4-6. O 2 Sensor Reading P(kPa) O 2 % 60 40 30 20 10 6.5 508.2 490.6 481.6 476.1 469.1 14.0 2375.5 1696.2 1380.2 1083 785.4 18.5 3438.2 2377.2 1882.8 1401.2 953.1 30.3 5351.5 3588.2 2770.2 1993.0 1244.0 29.8 5350.5 3609.7 2787.73 2004.7 1261.7 34.0 6477.5 4297.7 3281.53 2330.1 1429.1 O 2 sensor A similar procedure was followed for O 2 . Table 4-6 is the O 2 sensor reading at different pressure and O 2 concentration. The O 2 concentrations were the results from GC. Plot the O 2 reading vs. P, as in Figure 4-11. For a certain total pressure, the sensor output was linear to the O 2 %, which meant O 2 sensor output was a function of pressure and O 2 percentage, and the function had a form like: )(%)(Re22PgOPfadO Eq.4-12 In which, O 2 Read: reading from O 2 sensor O 2 %: O 2 percentage P: pressure (kPa)

PAGE 57

47 y = 32.721x + 297.81R2 = 0.9885y = 63.565x + 137.85R2 = 0.9907y = 96.155x 35.82R2 = 0.9909y = 130.67x 222.34R2 = 0.9912y = 204.57x 621.33R2 = 0.9914010002000300040005000600070000510152025303540O2%O2dt 40 kpa 30 kPa 20 kPa 10 kPa 60kPa Linear(10 kPa) Linear(20 kPa) Linear(30 kPa) Linear(40 kpa) Linear(60kPa) Figure 4-11. O 2 reading vs. Pressure In order to get the function of f(P) and g(P), first the slope and interception of each line were listed in Table 4-7. Plot the slope and intercept vs. P, as in Figure 4-12. From Figure 4-12, 6998.44448.3)( PPf Eq.4-13 73.501453.18)( PPg Eq.4-14 Putting Eq.4-13 and Eq.4-14 into Eq.4-12, gave 73.501453.18%)6998.4448.3(Re22 POPadO Eq.4-15 Rearranging Eq.4-15, gave 6698.44448.373.501453.18Re%22PPadOO Eq.4-16

PAGE 58

48 Table 4-7. Slope and Intercept for Each Line P 60 40 30 20 10 slope 204.57 130.7 96.2 63.6 32.7 intecept 621.33 -222.3 -35.8 137.9 297.8 y = 3.4448x 4.6988R2 = 0.9984y = -18.453x + 501.73R2 = 0.9978-800-600-400-2000200400010203040506070P (kPa)O2dt slope intercept Linear(slope) Linear(intercept) Figure 4-12. Slope and Intercept vs. P One note about the above sensor calibration was, for GMM221 CO2 sensor and O2 sensor the sensor reading was plotted vs. the gas concentration, while for GMM222 CO2 sensor, the sensor reading was plotted vs. the pressure. Actually the sensor response was linear to both gas concentration and pressure for all three sensors. And sensor reading

PAGE 59

49 was plotted vs. both gas concentration and pressure, and the one that fitted better were chosen. Control Algorithm The environmental parameters inside the plant growth chamber, T, RH, P, ppCO 2 , ppO 2 and light were closely interconnected, see Figure 4-13 [Fowler et al., 2002]. Effective control of each parameter separately was critical to find out how each parameter influences plant growth separately. In this project, temperature and light were controlled by putting the whole system inside the big plant growth chamber, while P, RH, ppCO 2 and ppO 2 were controlled by the following algorithm. Plant Growth Pressure Gas Composition Light Humidity Temperature Figure 4-13. Relationships of Environmental Parameters RH Control The RH was controlled by the thermoelectric cooling unit at the bottom of the chamber. Plant transpiration increased the RH, while at the same time water condensed on the cold surface of the thermoelectric unit, which was regulated by its temperature. To maintain a certain RH the temperature of thermoelectric unit was adjusted according to the plant transpiration rate and RH set point. The temperature of thermoelectric unit was

PAGE 60

50 determined by the voltage supplied to it. The temperature control changes were made by adjusting the duty cycle (DC) of the voltage with PWM (Pulse Wise Modulation). PID control was used, with the increment in DC as a function of RH error, as seen in equation 4-17: ])2[(])1[(][][TkecTkebkTeakTDC Eq. 4-17 in which, DC: increment in DC e[kT], e[(k-1)T], e[(k-2)T]: error at kT, (k-1)T, and (k-2)T; T: Sampling period a, b, c: Parameters a, b, c and T were determined with the following steps: 1. Placed controller into automatic with low gain, no reset or derivative. 2. Gradually increased the gain, making small changes in the set point, until oscillations started. 3. Adjusted the gain to make the oscillations continue with a constant amplitude. 4. Noted the gain (Ultimate Gain, G u ,) and Period (Ultimate Period, P u .) The Ultimate Gain, G u , was the gain at which the oscillations continue with a constant amplitude. 5. Then T= P u /10, a = 2.45G u , b= -3.5G u , and c = 1.25G u G u was found to be 20, and P u was 100 second. Put them into equation 4-17: ])2[(30])1[(70][45][TkeTkekTekTDC Eq. 4-18 And since the maximum of DC is 100 and minimum is 0, these two limitations were added to equation 4-17: If DC>100, DC=100 If DC<0, DC=0

PAGE 61

51 Gas Control Figure 4-14. Flowchart of the Gas Control Algorithm Total pressure, ppO 2 and ppCO 2 were controlled separately. Pressure was controlled first, because the CO 2 and O 2 sensors were calibrated between the pressure of 5-50 kPa. Pressures out of this range could cause big errors in sensor readings. So pressure was controlled to the set point first by pumping down when it is high, and adding nitrogen when it is low. For ppO 2 , if it was high, gas was pumped out till ppO 2 No No Yes No No Yes No Yes No No Yes Yes Yes Collect Data P>P Set Pump Down O 2 > O 2 Set No Calculate NewPSet Pump Down P>NewP Set Add N 2 N 2 N 2 Set No Calculate NewPSet Pump Down P>NewP Set Add O 2 O 2 CO 2 Set Yes No Yes Calculate NewPSet Pump Down P>NewP Set Add O 2 , N2 O 2
PAGE 62

52 reached the set point and then N 2 was added back. The amount of gas needed to be pumped out was decided by equation 4-19: SetppOppOPNewPSet22 Eq. 4-19 If ppO 2 was low, which means N 2 was high, a similar method was followed as for O 2 , pumping down and then adding O 2 back. CO 2 was controlled at the end, because with 0-5000ppm of CO 2 , the maximum ppCO 2 would only be 0.5kPa, which was not going to influence the total pressure and ppO 2 substantially. So CO 2 was added back after O 2 and N 2 reached the set point. If CO 2 was high, a similar method to O 2 was used, pumping down and adding back the O 2 and N 2 . See Figure 4-14 for details. Distributed Computer Control System System Structure The control hardware had to be flexible and scalable enough to accommodate various research configurations, while keeping the development cost and subsequent programming effort low. The hardware design, developed by Rigel Corporation specifically for this mission, was based on a distributed control system using multiple low-cost processors [Fowler et al., 2002]. The distributed computer control system consisted of three subsystems, the adapter boards, the sub processor and the host processor (PC), as seen in Figure 4-15. The adapter boards, such as the ADC board, TC (thermocouple) board, and PIO board, read from sensors, did A/D conversion, and sent out control signals. The adapter boards were plugged into the baseboard, which housed the sub processor and the power supply. Most of the control work was done by the adapter boards. The baseboard had a

PAGE 63

53 series of sockets for the adapter boards. Any combination of the adapter boards might be plugged into the baseboard. This provided much needed flexibility. RS232 host p rocesso r ADC b oar d sensors PIO b oar d sub processor TC b oar d TCs relays sub p rocessor EEPROM Figure 4-15. Schematic Diagram for the Distributed Control System The adapter boards also contained “smart” chips with on-board data processing capabilities. For instance, several ADCs contained on-chip intelligence to configure and condition the input signals. Such smart chips made it feasible to use the same hardware for the various analog inputs, such as load cells, humidity sensors, and light level sensors. One such adapter board used the ADS1241 chip to read 24-bit analog inputs. An example will be given later to show how to use the on-chip intelligence to read load cells. The digital inputs and outputs were implemented by a microcontroller running in single chip mode on the PIO board. That is, all the code and data memory were on the same micorcontroller. In this sense, these controllers were similar to the “smart” chips. However, they were fully programmable to allow future customization as the research needs arise. The sub-processor on the baseboard managed the adapter boards and communicated with the host processor through RS232. Data from the ADC boards could be temporarily stored in their memory. They could also receive set points from the PC

PAGE 64

54 and send data to it on command. They sent out control signals to the PIO board based on the control algorithm. The PC stored data in database and sent set points to the sub processors. Load Cell Subsystem Each load cell was a Wheatstone bridge, supplying a differential voltage proportional to the weight. Analog signals from the load cells were sent to the analog-to-digital converters (ADC). The ADCs were type ADS1241, manufactured by Burr-Brown, now a subsidiary of Texas Instruments. The ADS1241 was a precision, wide dynamic range A/D converter operating from 2.7V to 5.25V supplies. The delta-sigma A/D converter provided up to 24 bits of conversion values with no missing codes. Its effective resolution was 21 bits. Compared to the older generation ADCs, the ADS1241 was a "smart" chip. It has several modes of operation and a programmable analog front end for signal conditioning. It also performed self-calibration functions. The conversion values could be modified by a 24-bit offset. The offset determined the input voltage that gave a zero conversion result. Similarly, the conversion value per mill volt input could be programmed. This effectively determined the input voltage that generated the maximum (full-scale) conversion value. The ADS 1241 was controlled by a synchronous serial port, implemented using only three signal lines. The communications between the processor and the ADS1241 consisted of commands issued by the processor and the data read from the ADS1241. More specifically, the processor wrote to control registers in the ADS1241 to configure the chip and issue commands. The status of the chip as well as conversion results were read from the status and data registers of the ADS1241. Since differential inputs were

PAGE 65

55 used, each ADS1241 could read four load cells. The adaptor card housed four ADS1241 chips. Therefore, each adaptor card could read up to 16 load cells. An accuracy of 100mg was chosen. A nominal pot weight of 2kg 100g was assumed. When the seeds were placed, each ADS1241 channel was "zeroed out." That is, the ADS 1241 was programmed with the appropriate offset value to return a conversion result of zero. Next, the ADC1241 channel was calibrated. A 100g weight was used, and the ADS1241 channel was programmed to output a value of 2000. Once calibrated, the ADC conversion result has a resolution of 100/2000 g, or 50mg. Although the differential inputs were relatively insensitive to common mode effects, there was still some signal noise and load cell drift. A moving average methodology was implemented to further filter high frequency elements of the conversion data sequence. The method simply averaged the most recent N observations. The parameter N was referred to as the window size, or the sample size. A new average was obtained each time a new conversion was performed. Let X(i) be the i-th conversion result and Y(i) be the i-th average. Then, Y(i) = Y(i-1) + (X(i) – X(i-n)) / N The average Y(i) was valid after the first N conversions. The method gave an accuracy of mg, as desired. Software The major aspects of software were to deal with many different levels of interfacing from the system to the real world. The following are the levels described in more details from top down. Human to PC The human to PC interface was developed in Visual C++, which is a visual development package that produces a windowed environment. The system primary

PAGE 66

56 screen, as seen in Figure 4-16, was used to display the real-time values of the environmental parameters monitored, both in tables and diagrams. It could also display and change set points. Figure 4-16. User Interface PC to Databases Data collected were stored in Access. Interface between the main program and Access was done through ODBC (Open Database Connectivity). First, an ODBC data source “greenhouse” was defined, which consisted of the specific set of data, the information required to access that data, and the location of the data source. To access data provided by the data source, the program established a connection to the data source. All data access was then managed through that connection. Data-source connections were

PAGE 67

57 encapsulated by class CDatabase. Once a CDatabase object was connected to the data source, the following function could be realized: Construct recordsets, which select records from tables or queries. Manage transactions, batching updates so all are “committed” to the data source at once (or the whole transaction is “rolled back” so the data source is unchanged) — if the data source supports the required level of transactions. Directly execute Structured Query Language (SQL) statements. PC to Microcontroller The PC to microcontroller interface mainly dealt with the serial communication between a serial port on PC and a serial port on the mother board. In order to do this, a MSComm control was added to the program. The MSComm control provided an interface to a standard set of communications commands. It encapsulated several properties, such as Input, Output, Settings, CommEvent, which allowed to establish a connection to a serial port, issue commands, exchange data, and monitor and respond to various events and errors that may be encountered during a serial connection. Microcontroller to Adaptor boards The adapter boards contained “smart” chips with on-board data processing capabilities. The microcontroller needs drivers for each “smart” chip to read data or send out command. The drivers were written with the help from the company that developed the board. Figure 4-17 showed the software structure of the microcontroller. Drivers (functions) for ADC board, PIO board and EEPROM were written in “ADC.c”, “eeprom.c” and “pio.c”. The main program “main.c” only needed to call these functions when it wanted to read data or send out a command.

PAGE 68

58 main.c base.h ADC EEPROM PIO PIO.c PIO.h eeprom.c eeprom.h base.h ADC.c ADC.h base.h Sub Processor Figure 4-17. Schematic Diagram for the Software Structure Plant Tests Soybean (cultivar “Biloxi”) was used as the plant material. A series of plantings were established at about 2-3 day intervals to handle the fact that the plants will grow quickly too large to fit in the “bell-jar” reduced total atmospheric pressure apparatus. Comparison (control) plants were grown in the growth chamber. Soybean seeds were planted and grown in organic potting mix under normal atmosphere (Figure 4-18). Table 4-8 shows the normal experimental conditions. Twenty days after being planted, soybean plants were transferred into Eolen meyer flasks, which contained pH-buffered complete nutrient solution and were wrapped with aluminum foil. Previous experiments done with potting mixture sealed with plastic tape were not successful, because the gases released from the organic mixture contaminated the CO 2 measurements. Flasks with a stopper at the top totally sealed the flasks and prevented any CO 2 gas or water vapor release except from the plant. Plants were then exposed to different test conditions for about one hour (Figure 4-19). Three total pressure (70, 50, and 25kPa) and three light levels were used (540, 320, and 200 mol/m 2 /s) (Table 4-9). CO 2 uptake rate was measured by the conventional assimilation chamber technique. Briefly, the ppCO 2 was brought to 100Pa and then the control valve and gas supply were

PAGE 69

59 shut off, and the plants were then exposed to light for about one hour. The change in ppCO 2 was used to calculate the CO 2 uptake rate. Table 4-8. Common Experimental Conditions Temperature Light Source PPFD RH Light Period 25 C Metal Halide Lamp 400 mo l m -2 s -1 50% 18 h Table 4-9. Experiment Pressure and Gas Conditions Pressure (kPa) PPFD (mol/m 2 /s) CO 2 (Pa) O 2 (kPa) RH (%) 25 540 100 5 75 50 540 100 5 75 70 540 100 5 75 25 320 100 5 75 50 320 100 5 75 70 320 100 5 75 25 200 100 5 75 50 200 100 5 75 70 200 100 5 75 Figure 4-18. Soybean Plants Growing under Normal Atmosphere

PAGE 70

60 Figure 4-19. Plant Test in Bell Jar Apparatus

PAGE 71

CHAPTER 5 RESULTS AND DISCUSSION Leakage Test The leakage rates were calculated from the rates of pressure change. Pressures at the beginning and end of a 60min interval were recorded, and leakage rate was calculated with the following equation: tPPPLi144010000 Eq. 5-1 where, L: leakage rate (%volume/day) P 0 : initial pressure (kPa) P i : end pressure (kPa) t: time interval (min) Table 5-1 shows the leakage rates at three initial pressures. Leakage rates increase with the decrease in the inside pressure, which corresponds to an increase in the pressure difference between the inside and outside. Table 5-1. Leakage Rates for LPPG Chamber Trial # Initial pressure (kPa) End pressure (kPa) Pressure rate (kPa/min) Leakage rate (%volume/day) 1 10.84 10.90 10 -3 13.28 2 17.28 17.34 10 -3 8.33 3 24.35 24.38 50 -4 2.96 Sensor Calibration Half of the data collected during sensor calibration was used for calibration, while the other half of the data was used to verify the calibration equation. Table 5-2, 5-3 and 5-4 compared the true values and the values calculated from pressure and sensor reading with the calibration equation. Sensors’ accuracy was within 15% of readings for pressure 61

PAGE 72

62 between 20~50kPa. Most of the big errors occurred at the pressure of 10kPa. A solution to this problem was, for pressures under 20kPa, instead of including pressure in the calibration equation, use the regression function at that pressure. For example, for GMM221 CO 2 sensor at 10kPa, use Eq. 5-2 instead of Eq. 4-6. Eq.5-2 was obtained from Figure 4-6 on page 41. The value was listed in Table 5-2. The error was greatly reduced. 3.3058.508Re%22adCOCO Eq. 5-2 Table 5-2. CO 2 Sensor Test (GMM221) 50 40 30 20 10 [1] 10 [2] P(kPa) CO 2 % CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) 2.1 2.30 9.3 2.15 2.40 2.10 2.54 2.06 1.7 2.54 21.1 2.08 0.8 1.0 0.97 3.4 0.96 4.22 0.97 1.10 0.93 7.3 1.10 10.1 1.01 1.1 3.4 3.46 1.8 3.25 4.31 3.10 4.10 3.20 5.9 4.10 20.7 3.24 4.6 [1]: calculated with Eq. 4-6 [2]: calculated with Eq. 5-2 Table 5-3. CO 2 Sensor Test (GMM222) 50 40 30 20 10 P(kPa) CO 2 (ppm) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) CO 2 cal Error (%) 420.2 366.4 12.8 396.3 5.7 466.8 11.1 510.8 21.6 414.8 1.3 938.0 906.0 3.4 948.8 1.2 938.5 0.06 893.0 4.8 677.3 27.8 2279.4 2339.4 2.6 2280.1 0.03 2287.3 0.4 2344.0 2.8 2400 5.3 3632.8 3679.1 1.3 3557.8 2.1 3502.1 3.6 3469.1 4.5 3503 3.6 Table 5-4. O 2 Sensor Test 60 40 30 20 10 P(kPa) O 2 (kPa) O 2 cal Error (%) O 2 cal Error (%) O 2 cal Error (%) O 2 cal Error (%) O 2 cal Error (%) 6.46 5.5 14.2 5.5 15 5.44 15.83 5.4 16.7 5.1 20.44 14.0 14.8 5.3 14.6 3.61 14.5 3.59 14.8 5.63 15.8 12.31 18.5 20 8.24 19.7 6.18 19.6 6.043 19.8 6.84 21.41 15.58 29.8 29.5 1.01 28.9 2.99 28.8 3.36 29.2 2.1 31.8 6.586 34.0 35.1 3.33 34.1 0.39 33.8 0.423 34.3 0.87 37.4 10.14

PAGE 73

63 Control Without Plants Control without plants was done by giving new set-points to see the response of the system. Table 5-5 lists the test conditions for CO 2 control, which are, changing CO 2 set point from 0.2 to 0.5 kPa or 500 to 2000 ppm for different pressures: Table 5-5. Test Conditions for CO 2 Control P (kPa) CO 2 20 0.2->0.3->0.4->0.5 (kPa) 30 0.2->0.3->0.4->0.5 (kPa) 40 0.2->0.3->0.4->0.5 (kPa) 20 500->1000->2000 (ppm) 50 500->1000->2000 (ppm) Figure 5-1 and 5-2 shows how well the control could follow the set point change. The overshoot was less than 20%. The settling time was less than 5 minutes. The steady state error was less than 10% of set point. The overshoot was likely caused by the time needed for the gas to mix well and the delay in sensor response. Another test was done for RH control, by changing the RH set point from 90% to 75% to 60% for different pressures. The result is in Figure 5-3. The overshoot was less than 5%. The settling time was less than 5 minutes. The steady state control error was less than 5%. Table 5-6. Test Conditions for RH Control P (kPa) RH Set (%) 25 50 75 90->75->60

PAGE 74

64 00.10.20.30.40.50.60.7050100150200250300t (min)CO2(kPa) CO2St CO2 Figure 5-1. CO 2 (kPa) Control Test 05001000150020002500010203040t(min)CO2 (ppm) CO2St CO2 Figure 5-2. CO 2 (ppm) Control Test

PAGE 75

65 505560657075808590950102030405060708090100t (min)RH (% ) RHSet RH Figure 5-3. RH Control Test Plant Responses to Different Conditions Effects of Pressure and CO 2 Concentration on CO 2 Uptake Rate Figure 5-4 shows the CO 2 uptake rates at different total pressures. When ppCO 2 was lower than 25Pa, differences between CO 2 uptake rates at three different total pressures were not apparent. After CO 2 went above 25kPa, the higher the pressure, the higher the CO 2 uptake rates and the higher the CO 2 saturation point. This is different from what has been reported in most references, which is, reduced pressure increased the CO 2 uptake rate. However, most reported studies did not seem to be reliable due to methodological insufficiencies, such as leakage and sensor response under low pressure. In this project, sensors were tested and calibrated under low pressure, and leakage rates were less than 10% volume /day at pressures tested, which was good enough for the 1 hour short term test. And all the data obtained so far looked reasonable. So it is believed

PAGE 76

66 that the observed phenomena were the real plant response, instead of being caused by instrumentation error. Effects of Pressure and Light on CO 2 Uptake Rate Figure 5-5 shows the CO 2 uptake rates at these light levels. The CO 2 uptake rates increased with increased light level. The light compensation point was about 200 mol/m 2 /s. 0510152025020406080100CO2(Pa)CO2 (mol/m2/s) 70kPa 50kPa 25kPa Figure 5-4. CO 2 Uptake Rates of Soybean under Different Total Pressure. T = 25C RH = 75% PAR = 530mol/m2/s ppO 2 = 5kPa

PAGE 77

67 05101520250100200300400500600PPFD (mol/m2/s)CO2 Uptake Rate ( mol/m2/s ) 25kPa 50kPa 70kPa Figure 5-5. CO 2 Uptake Rates of Soybean under Different Light Levels. T = 25C RH = 75% ppO 2 = 5kPa Methodology for Developing Low Pressure Plant Growth Chamber Based on the research experience of this project, a methodology was generalized for developing low-pressure plant growth systems. The methodology can be divided into the 8 steps. This project is used as an example to demonstrate how this methodology woks: 1. Define the research objectives: influence of total pressure and gas partial pressure on plant growth. 2. Define the variables to be controlled and measured, the requirement for measurement and control. The major variables measured and controlled were listed in Table 5-7. 3. Design the system hardware: including structure design, selection of fittings and tubing, and leakage test. 4. Selection and calibration of sensors and control equipment for each variable according to measurement and control requirement listed in step 2. Sensors for this project were listed in Table 4-1. 5. Design of control system, including

PAGE 78

68 a. Selection of the computer, whether it is PC, or microcontroller, or other industrial computer; b. Selection of ADC and DACs. c. Design the interfaces between the computer, ADC, DAC, sensors and control equipments: distributed control system is selected because replicate experiments may be needed. This project used a MCS51 microcontroller based electronic board developed by Rigel Corp, which included all the ADC, DAC, and interfaces on it. Affordable commercial electronic control boards are also available in the market, which means you do not have to design your own board if you do not have an electronic engineering background or you want to spend more time with other details. Table 5-7. Variables Measured and Controlled Variables Measurement Requirement Control Requirement Temperature 1 C 1 C RH 5% % Light 5%FS* % Pressure 1%FS 1% CO 2 10%FS 10% O 2 %FS 5% Mass Flow %FS % FS*: full scale 6. Design of control algorithm for each variable to be controlled. Usually the control algorithm is designed based on the system mathematical model. However, plant growth as a biological system, is a multi-input-multi-output system, with these inputs and outputs interacting with each other, as seen in Figure 4-6. It is hard to build a complete mathematical model for such a system. So instead, PID control was used with its parameters tuned with experience. Fuzzy control may also be a good option. 7. Test of the whole system, including test the system with and without plants. Tests without plants are to find out how well the system follows the set point change, and to come up with the system performance, such as overshoot, and response time. Only after the system performs well without plants, should testing with plants start. 8. Do experiments to show how well the system meets the research needs. In this project, the system was able to provide various conditions required for plant tests.

PAGE 79

CHAPTER 6 Conclusions The system was sufficient for short term low pressure plant tests. Total pressure, partial pressures of CO 2 , O 2 , and N 2 , relative humidity were controlled, separately and efficiently. Temperature and lighting, although not included in the control algorithm, could also be adjusted manually. Data collection and real time control was all done in the microcontroller located in the big growth chamber. It can also receive command from PC. Software on the PC was able to communicate with the microcontroller and record data in database. Short term plant tests were conducted. This system was able to provide various environmental conditions that the tests required. The system was designed for small scale plant growth chamber, however, the technology developed in this project, such as sensor calibration techniques and control algorithms, can be used for large growth chambers as well. In fact, elements of the program have already been used on the Mars Dome project in Kennedy Space Center, and a Mars Simulation Chamber in Agricultural& Biological Engineering Department, University of Florida. An 8-step systematic approach was generalized for developing low-pressure plant growth systems, which will later help other people who want to set up similar system. 69 CONCLUSIONS AND FUTURE WORK

PAGE 80

70 Future Work Water Recycling The existing setup is not equipped with water recycling equipment except a water storage box with small capacity. This can be done through bringing condensed water back to the plant growth media, using wick material with strong capillary action. Bell Jar The bell jar is big enough for sensor testing and calibration, but not enough for plant test. The plant tests at the final stage of this project were limited by its size. Future research need to choose the bell jar or growth chamber size based on the research needs. Plant Tests More plant tests could be done to see the plant responses to O 2 , temperature and humidity. In the future, if multiple treatments need to be done, it is better to do them with several bell jars at same time. In this way other no-specific factors like temperature will be as identical as possible. Also as stated before, the distributed structure of this system allow itself to be easily extended to include more subsystems.

PAGE 81

APPENDIX A MICROCONTROLLER CODE main.cpp //main program 11/19/2003 #include #include #include "base.h" #include "ADC_1241.h" #include "PIO.h" #include "EEPROM.h" #include "SystemTime.h" //extern int ngSec; extern unsigned char bgDeviceLo, bgDeviceHi; //------------------------------------------------// ----------------------------------------------------//Data int nTmp, nRH, nWV, nPrs, nDryPrs, nCO2, nO2, nN2,nLght, nWght,nHm; int nN2V,nCO2V,nO2V; //Set points and address in eeprom int nTmpSt, nRHSt, nPrsSt,nDryPrsSt, nWVSt,nTws, nN2St,nCO2St, nO2St,nCO2DeadBand; int nTmpStAdrs, nRHStAdrs, nPrsStAdrs, nCO2StAdrs, nO2StAdrs; //Controls int nNwPrsSt, nNwCO2St,nNwO2St,nNwN2St,nNwWvSt, nN2Add, nO2Add, nCO2Add, nN2DC, nO2DC, nCO2DC, nECO2, nEO2, nEN2, nERH0,nERH1,nERH2,nERHSum,nEWV,; int nN2DC1, nO2DC1, nCO2DC1,nRHDC, nRHKp; int nControl; int nMn, nSc; UINT nXH, nXL, nYH, nYL; void main(void){ int i,j; // initialize serial port SCON=0x50; 71

PAGE 82

72 T2CON=0; RCAP2H=0xFF; RCAP2L=0xF3; // 57600 Baud //RCAP2L=0xB2; // 9600 Baud T2CON=0x34; TI=1; RI=0; EA=0; ES=1; EA=1; cputs("Initializing the time ...\n"); Time_InitSystemTime(); cputs("Atmospheric Tower Control System ...\n"); nTmpStAdrs=0; nRHStAdrs=2; nPrsStAdrs=4; nCO2StAdrs=6; nO2StAdrs=8; nTws=1584;//Tws=3.169kPa, nTws=3.169*500 nControl=1; nERH0=0; nERH1=0; nERH2=0; nERHSum=0; nRHKp=10; nRHDC=0; //Control reset PIO_SetDC(PIO_1, 2, 1, nRHDC); PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF); PIO_SetDac(DEVICE_DAC, N2_BIT, 0); PIO_SetDac(DEVICE_DAC, O2_BIT, 0); PIO_SetDac(DEVICE_DAC, CO2_BIT, 0); ADC_Reset(4); ADC_Reset(6); ADC_Reset(7); while(TRUE) { if(nControl==0) { PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF);

PAGE 83

73 PIO_SetDac(DEVICE_DAC, N2_BIT, 0); PIO_SetDac(DEVICE_DAC, O2_BIT, 0); PIO_SetDac(DEVICE_DAC, CO2_BIT, 0); } //if(peekc()) HandleSerialCmd(); //Get setpoints from EEPROM if(nControl==1) GetSetPoints(); //if(peekc()) HandleSerialCmd(); //Collect data CollectData(); if(nControl==1) PrsControl(); //if(peekc()) HandleSerialCmd(); CollectData(); //Caculate Setpoints for N2 and Dry pressure //if(peekc()) HandleSerialCmd(); if(nControl==1) CalSetPoints(); //if(peekc()) HandleSerialCmd(); if(nControl==1) GasControl(1); } }. function.c #include #include #include "base.h" #include "ADC_1241.h" #include "PIO.h" #include "EEPROM.h" #include "SystemTime.h" extern unsigned char bgDeviceLo, bgDeviceHi; extern int nTmp, nRH, nWV, nPrs, nDryPrs, nCO2, nO2, nN2,nLght, nWght,nHm; extern int nN2V,nCO2V,nO2V; //Set points and address in eeprom extern int nTmpSt, nRHSt, nPrsSt,nDryPrsSt, nWVSt,nTws, nN2St,nCO2St, nO2St,nCO2DeadBand; extern int nTmpStAdrs, nRHStAdrs, nPrsStAdrs, nCO2StAdrs, nO2StAdrs; //Controls extern int nNwPrsSt, nNwCO2St,nNwO2St,nNwN2St,nNwWvSt, nN2Add, nO2Add, nCO2Add, nN2DC, nO2DC, nCO2DC, nECO2, nEO2, nEN2, nERH0,nERH1,nERH2,nERHSum,nEWV,; extern int nN2DC1, nO2DC1, nCO2DC1,nRHDC, nRHKp; extern int nControl;

PAGE 84

74 extern int nMn, nSc; extern UINT nXH, nXL, nYH, nYL; // ----------------------------------------------------void InitSerial(void){ SCON=0x50; T2CON=0; RCAP2H=0xFC; RCAP2L=0xDF; T2CON=0x34; TI=1; RI=0; } // ----------------------------------------------------void SelectDevice(int nDevice){ int nMask; bgDeviceLo = 0xFF; bgDeviceHi = 0xBF; // RTC has hi-logic CE if(nDevice<0) return(FALSE); if(nDevice>15) return(FALSE); if(nDevice<8) { bgDeviceLo = ~(1<
PAGE 85

75 // ----------------------------------------------------void Nop() {} // ----------------------------------------------------int GetDec(void){ int nDec, nC; nDec=0; while(TRUE) { nC=getc(); // putc(nC); if(nC<'0'||nC>'9') break; else nDec=10*nDec+nC-'0'; } //T cprintf("\n%d\n",nDec); return(nDec); } // ----------------------------------------------------void interrupt(0x23) Serial_Isr(void){ char cCommand; int nNum, nDC; //cprintf("serial interrupt!\n"); if(RI) { cCommand = getc(); if(!(cCommand=='A')) { if(cCommand=='Y') cprintf("Get Y"); else{ nNum = GetDec();; if((cCommand=='W')||(cCommand=='M')||(cCommand=='C')) nDC=GetDec(); } } RI=0; //cprintf("Received command: %c%d\n", cCommand,nNum); HandleCommand(cCommand,nNum,nDC); } } void HandleSerialCmd(){ /* char cCommand; int nNum, nDC; //cprintf("serial interrupt!\n");

PAGE 86

76 // ES=0; // if(RI) // { cCommand = getc();//SBUF; putc(cCommand); // echo if(!(cCommand=='A')) { nNum = GetDec(); if((cCommand=='W')||(cCommand=='M')||(cCommand=='C')) nDC=GetDec(); } //RI=0; //cprintf("Received command: %c%d (%d)\n", cCommand,nNum,nDC); HandleCommand(cCommand,nNum,nDC); // } // ES=1; */} // ----------------------------------------------------void Abs(int n){ if(n<0) n=-n; return(n); } // ----------------------------------------------------int Max(int x1, int x2, int x3){ int nMx; nMx = (x1>x2) ? x1 : x2; nMx = (x3>nMx) ? x3 : nMx; /*if(x1>x2) nMax = x1; else nMax = x2; if(nMaxx2) ? 1 : 2; nMx = (x1>x2) ? x1 : x2;

PAGE 87

77 nMxIndx = (x3>nMx) ? 3 : nMxIndx; nMx = (x3>nMx) ? x3 : nMx; nMxIndx = (x4>nMx) ? 4 : nMxIndx; nMx = (x4>nMx) ? x4 : nMx; /*if(x1>x2) nMax = 1; else nMax = 2; if(nMax>8; uXL=uX&0xFF; uYH=uY>>8; uYL=uY&0xFF; //cprintf("uXH=%x uXL=%x uYH=%x uYL=%x\n", uXH, uXL, uYH, uYL); u0=uXL*uYL; u1=uXL*uYH+uXH*uYL; uCarry = ( (u1>8) + uCarry; //cprintf("uRH=%x uRL=%x uC=%x\n", uRH, uRL, uCarry); *puRH=uRH; *puRL=uRL; } void Div32(UINT uXH, UINT uXL, UINT uDiv, UINT *puRH, UINT *puRL){ UINT uRL, uRH, uTmp,uC; int i; uRH=0;

PAGE 88

78 uRL=0; uTmp=0; //cprintf("Before Div: %x %x %x/ %x = %x %x\n", uTmp, uXH,uXL, uDiv, uRH, uRL); for(i=0;i<32;i++) { //cprintf("uRH before Div: %x %x %x / %x = %x %x\n", uTmp, uXH,uXL, uDiv, uRH, uRL); uC=(uTmp&0x8000)>>15; //uTmpH=(uTmpH<<1)+((uTmpL&0x8000)>>15); uTmp=(uTmp<<1)+((uXH&0x8000)>>15); uXH=(uXH<<1)+((uXL&0x8000)>>15); uXL=uXL<<1; //cprintf("uRH after Div: %x %x %x / %x = %x %x\n", uTmp, uXH,uXL, uDiv, uRH, uRL); if((uTmp>=uDiv)||(uC==1)) {uC=1; uTmp=uTmp-uDiv;} else uC=0; uRH=(uRH<<1)+((uRL&0x8000)>>15); uRL=(uRL<<1)+uC; } *puRH=uRH; *puRL=uRL; } // ----------------------------------------------------int GetCO2(int nDevice, int nUnit, int nPGA){ int nRwDt, nCO2_PPM; UINT nXH,nXL,nYH,nYL,nTmp; nRwDt=ADC_GetDiffVoltage(nDevice,nUnit, nPGA); //CO2(ppm) = (nRwDt-541.7652-9.4794*P)/(0.04658*P-0.08837) if(nRwDt<(542+nPrs*19/10)) {nCO2_PPM=0; nCO2=0;} else { nTmp=nRwDt-542-nPrs*19/10; Mul32(nTmp, 1000, &nXH, &nXL); Div32(nXH,nXL,(46*nPrs/5-9),&nYH, &nYL); nCO2_PPM=nYL; Mul32(nCO2_PPM, nPrs, &nXH, &nXL); Div32(nXH,nXL,500,&nYH, &nYL); nCO2=nYL; } /*if(nRwDt<2204) nCO2=0; else { nTmp=nRwDt-2204; Mul32(nTmp, nPrs, &nXH, &nXL); Div32(nXH,nXL,696,&nYH, &nYL); nCO2=nYL;

PAGE 89

79 } if(nRwDt<1340) nCO2=0; else { Mul32((nRwDt-1340), nPrs, &nXH, &nXL); Div32(nXH,nXL,484,&nYH, &nYL); nCO2=nYL; } /* nCO2=(nRwDt-2064)/25*nPrs/50; if(nCO2<0) nCO2=0;*/ /*if(nRwDt<1340) nCO2=0; else { Mul32((nRwDt-1340), nPrs, &nXH, &nXL); Div32(nXH,nXL,484,&nYH, &nYL); nCO2=nYL; } //ppCO2=P*(nRwDt-50.472*P-662.6)/(30.636*P-182.42) if(nRwDt<(50*nPrs/5+662)) nCO2=0; else { nTmp=nRwDt-50*nPrs/5-662; Mul32(nPrs, nTmp, &nXH, &nXL); //putc('\n'); Div32(nXH,nXL,30*nPrs/5-182,&nYH, &nYL); nCO2=nYL; } //ppCO2=P*(nRwDt-29.595*P-199.65)/(39.352*P-166.69) if(nRwDt<(30*nPrs/5+200)) nCO2=0; else { nTmp=nRwDt-30*nPrs/5-200; Mul32(nPrs, nTmp, &nXH, &nXL); //putc('\n'); nTmp=39*nPrs/5-167; Div32(nXH,nXL,nTmp,&nYH, &nYL); nCO2=nYL; }*/ //cprintf("%d %d %d %d\n", nPrs, nRwDt, nCO2,nTmp); //cprintf("%d %d ", nRwDt, nCO2); //putc('\n'); cprintf("%d %d %d ", nRwDt,nCO2_PPM, nCO2); return(nCO2);

PAGE 90

80 } // ----------------------------------------------------int GetO2(int nDevice, int nUnit, int nPGA){ int nRwDt, nO2; UINT nXH, nXL, nYH, nYL,nTmp; nRwDt=ADC_GetDiffVoltage(nDevice,nUnit, nPGA); /* nO2=(nRwDt-222)/26*nPrs/5; if(nRwDt<138) nO2=0; else { Mul32((nRwDt-138), nPrs, &nXH, &nXL); Div32(nXH,nXL,63,&nYH, &nYL); nO2=nYL; }*/ //ppO2=P*(nRwDt+18.45*P-501.73)/(3.44*P-4.67) if(nRwDt<-37*nPrs/10+502) nO2=0; else { nTmp=nRwDt+37*nPrs/10-502; Mul32(nPrs, nTmp, &nXH, &nXL); Div32(nXH,nXL,(17*nPrs/5-23)/5,&nYH, &nYL); nO2=nYL; } //cprintf("%d %d %d\n", nRwDt, nO2, nTmp); //cprintf("%d %d\n", nRwDt, nO2); return(nO2); } int GetWeight(int nDevice, int nUnit, int nPGA, int nCountLimit){ int n0, n1, nSum,nCount, n[10], nAvg, nCnt; nCnt=0; n0=ADC_GetDiffVoltage(nDevice,nUnit, nPGA); n[0]=n0; cprintf("%d ", n0); for(nCount=1; nCount
PAGE 91

81 nAvg = n0+nSum/nCountLimit; cprintf("Avg:%d \n", nAvg); cprintf("Filter...\n"); if((n[0]>nAvg-20)&&(n[0]nAvg-20)&&(n[nCount]100) nRH=100; //cprintf("%d %d ", nRwDt, nRH); return(nRH); } // ----------------------------------------------------void HandleCommand(char cCmd, int nNum, int nDC) { int nDvc, nPrt,nBt,nChnnl,nData; //cprintf("Handling command: %c%d\n", cCmd,nNum); switch(cCmd) { //routines to handle commands;

PAGE 92

82 case 'S': //shut everything off //turn heater off /*nDevice=PIO_1; nPort=1; nBit=1; PIO_WriteBit(nDevice, nPort, nBit, 1); nAirHtr=0; //cprintf("heater:OFF "); */ break; case 'C': //Set points // putc('C'); nChnnl=nNum; switch(nChnnl) { case 0: //cprintf("Please input the temperature:"); //nData = nNum%1000; nData = nDC; nTmpSt = nData*16; EE_WriteWord(nTmpStAdrs, nTmpSt); //cprintf("C%d(TmpSt),%d\n", nChnnl,nData); break; case 1: //cprintf("Please input the RH:"); //nRHSt = (nNum%100+26)*3; //nData = nNum%1000; nData = nDC; nRHSt = nData; EE_WriteWord(nRHStAdrs, nRHSt); //nRHAir=(GetRH(nDevice, 2))/3-26; //putc('C'); //cprintf("%d", nRHSt); cprintf("C%d(RHSt),%d\n", nChnnl,nData); //cprintf("%x : %d\n", nRHStAdrs, EE_ReadWord(nRHStAdrs)); break; case 2: //cprintf("Please input the presssure:"); //nData = nNum%1000; nData = nDC; nPrsSt = nData*5; EE_WriteWord(nPrsStAdrs, nPrsSt); //nRHAir=(GetRH(nDevice, 2))/3-26; cprintf("C%d(PrsSt),%d\n", nChnnl,nData); //cprintf("%x : %d\n", nPrsStAdrs, EE_ReadWord(nPrsStAdrs));

PAGE 93

83 break; case 3: //cprintf("Please input the CO2:"); //nData = nNum%1000; nData = nDC; nCO2St = nData*10; EE_WriteWord(nCO2StAdrs, nCO2St); //nRHAir=(GetRH(nDevice, 2))/3-26; //cprintf("%d%d", nCO2StAdrs, nCO2St); cprintf("C%d(CO2St),%d\n", nChnnl,nData); //cprintf("%x : %d\n", nCO2StAdrs, EE_ReadWord(nCO2StAdrs)); break; case 4: //cprintf("Please input the O2:"); //nData = nNum%1000; nData = nDC; nO2St = nData*500; EE_WriteWord(nO2StAdrs, nO2St); //nRHAir=(GetRH(nDevice, 2))/3-26; cprintf("C%d(O2St),%d\n", nChnnl,nData); //cprintf("%x : %d\n", nO2StAdrs, EE_ReadWord(nO2StAdrs)); break; } break; case 'A' : //putc('T'); //reads DS temperature chips //cprintf("%d%d%d%d%d%d%d%d%d%d%d", nBTmp,nBRH,nBPrs,nBCO2,nBO2,nBLght,nBWght,nRHSt,nPrsSt,nCO2St,nO2St); cprintf("%d%d%d%d%d%d%d%d%d%d%d", nTmp,nRH,nPrs,nCO2,nO2,nLght,nWght,nRHSt,nPrsSt,nCO2St,nO2St); break; case 'E' : nControl=nNum; if(nNum==0) cprintf("Control turned OFF!\n"); if(nNum==1) cprintf("Control turned ON!\n"); PIO_SetDac(DEVICE_DAC, nChnnl, nDC); break; /*case 'M' : nChnnl=nNum; cprintf("M%d,%d\r\n", nChnnl, nDC); PIO_SetDac(DEVICE_DAC, nChnnl, nDC); break; case 'K' : nRHKp=nNum; cprintf("Kp=%d\r\n", nRHKp); break; */

PAGE 94

84 } } void GetSetPoints(){ nTmpSt=EE_ReadWord(nTmpStAdrs); nRHSt=EE_ReadWord(nRHStAdrs); nPrsSt=EE_ReadWord(nPrsStAdrs); nCO2St=EE_ReadWord(nCO2StAdrs); nO2St=EE_ReadWord(nO2StAdrs); //cprintf("TmpSt(%x : %dC)\n", nTmpStAdrs, nTmpSt/16); cprintf("RHSt(%x : %d)\n", nRHStAdrs, nRHSt); cprintf("PrsSt(%x : %dkPa)\n", nPrsStAdrs, nPrsSt/5); cprintf("CO2St(%x : %dPa)\n", nCO2StAdrs, nCO2St/10); cprintf("O2St(%x : %dkPa)\r\n", nO2StAdrs, nO2St/500); } void CollectData(){ int nRwDt; nMn = Time_GetMin(); nSc = Time_GetSec(); cprintf("%d:%d ", nMn, nSc); //read light nLght=ADC_GetDiffVoltage(ADC_6, 1,7); if(nLght<0) nLght=0; //read weight ADC_WriteReg(4, 0x0A, 0xFF); ADC_WriteReg(4, 0x0B, 0xFF); ADC_WriteReg(4, 0x0C, 0xFF); nWght=ADC_GetDiffVoltage(ADC_4, 3,7); ADC_Reset(4); //read temperature nTmp = PIO_ReadTemp(PIO_T0, 0, 1); if(nTmp<0) nTmp=0; //Read RH nRH=GetRH(ADC_6, 0,0); nERH2=nERH1; nERH1=nERH0; nERH0=nRH-nRHSt; nRHDC+=49*nERH0-70*nERH1+30*nERH2; if(nRHDC>100) nRHDC=100;

PAGE 95

85 if(nRHDC<0) nRHDC=0; //if(nControl==1) //cprintf("%d:%d RHSt:%d RH:%d ERH0:%d ERH1:%d ERH2:%d nDC:%d\n", nMn,nSc,nRHSt,nRH,nERH0,nERH1,nERH2,nRHDC); PIO_SetDC(PIO_1, 2, 4, nRHDC); Mul32(nTws,nRH,&nXH,&nXL); Div32(nXH, nXL, 100, &nYH,&nYL); nWV=nYL; //nDryPrsSt=(nPrsSt*100-nWV)/100; //nN2St=nPrsSt*100-nO2St-nWV; //nDryPrs=(nPrs*100-nWV)/100; //nN2=nPrs*100-nO2-nWV; nDryPrs=nPrs-nWV/100; nN2=(nPrs-nO2/100-nWV/100)*100; nN2V=ADC_GetSingleEndVoltage(ADC_6, 6,0); nO2V=ADC_GetSingleEndVoltage(ADC_7, 2,0); nCO2V=ADC_GetSingleEndVoltage(ADC_7, 3,0); //read pressure nRwDt=ADC_GetSingleEndVoltage(ADC_6, 4,0); nPrs = (nRwDt-1597)/57; nCO2=GetCO2(ADC_7, 0, 0); nO2=GetO2(ADC_4, 0, 7); //cprintf("%d %d %d %d %d %d %d %d %d %d %d %d\n", nTmp,nRH,nRHDC,nPrs,nCO2,nO2,nLght,nWght,nRHSt,nPrsSt,nCO2St,nO2St); cprintf("%d %d %d %d %d %d %d %d %d %d %d\n", nTmp,nRH,nRHDC,nPrs,nCO2,nO2,nLght,nWght,nN2V,nO2V,nCO2V); } void CalSetPoints(){ //nDryPrsSt=(nPrsSt*100-nWV)/100; //nN2St=nPrsSt*100-nO2St-nWV; nDryPrsSt=nPrsSt-nWV/100; nN2St=(nPrsSt-nO2St/100-nWV/100)*100; if(nCO2St>=1000) nCO2DeadBand=nCO2St/20; if((nCO2St>=500)&&(nCO2St<1000)) nCO2DeadBand=nCO2St/10; if(nCO2St<500) nCO2DeadBand=nCO2St/5; if(nCO2DeadBand<20) nCO2DeadBand=20; if(nCO2DeadBand>100) nCO2DeadBand=100; } void PrsControl(){ int nRwDt;

PAGE 96

86 nRwDt=ADC_GetSingleEndVoltage(ADC_6, 4,0); nPrs = (nRwDt-1597)/57; //if((nControl==1)&&(Abs(nPrs-nPrsSt)>3)) if(Abs(nPrs-nPrsSt)>3) { if((nPrs-nPrsSt)>0) { PIO_SetDac(DEVICE_DAC, N2_BIT, 0); PIO_WriteBit(PIO_1, 0, PUMP_BIT, ON); PIO_WriteBit(PIO_1, 0, VLVE_BIT, ON); while((nPrs-nPrsSt)>2) { nRwDt=ADC_GetSingleEndVoltage(ADC_6, 4,0); nPrs = (nRwDt-1597)/57; cprintf("%d %d p>pSet\n ", nPrsSt, nPrs); //if(peekc()) HandleSerialCmd(); //CollectData(); //Wait(200); }; PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF); } else { if((nPrsSt-nPrs)>25) { CalSetPoints(); GasControl(0); } else { while((nPrsSt-nPrs)>0) { cprintf("%d %d p
PAGE 97

87 void GasControl(int bCO2){ int nRwDt; //O2200)//ppN2>0.5kPa { cprintf("\nO20); PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF); //add O2 till O2 reaches set point//read CO2 nO2DC=1000; PIO_SetDac(DEVICE_DAC, O2_BIT, nO2DC); do { //if(peekc()) HandleSerialCmd(); CollectData(); nEO2=nO2St-nO2; if(nEO2<500) { nO2DC=1000/20*(nEO2/30); PIO_SetDac(DEVICE_DAC, O2_BIT, nO2DC); } cprintf("%d %d\n", nEO2, nO2DC); }while(nO2St-nO2>50);//while((nDryPrsSt-nDryPrs)>0); PIO_SetDac(DEVICE_DAC, O2_BIT, 0); Wait(500);//delay for the sensor response time } //O2>02St else if(nN2St-nN2>200) { cprintf("\nN2
PAGE 98

88 //nNwPrsSt=nDryPrs/20*nO2St/(nO2/20); Mul32(nO2St,nDryPrs,&nXH,&nXL); Div32(nXH, nXL, nO2, &nYH,&nYL); nNwPrsSt=nYL; if(nNwPrsSt<30) nNwPrsSt=30; //pump down till O2 reaches set point PIO_WriteBit(PIO_1, 0, PUMP_BIT, ON); PIO_WriteBit(PIO_1, 0, VLVE_BIT, ON); do { //if(peekc()) HandleSerialCmd(); CollectData(); }while(nDryPrs-nNwPrsSt>0); PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF); //add N2 till N2 reaches set point PIO_SetDac(DEVICE_DAC, N2_BIT, 500); do { //if(peekc()) HandleSerialCmd(); CollectData(); //PIO_SetDac(DEVICE_DAC, N2_BIT, 1000); //cprintf("%d %d %d %d %d\n", nDryPrs, nDryPrsSt, nWV, nCO2, nO2); }while((nDryPrsSt-nDryPrs)>2);//while(nCO2St-nCO2>10); PIO_SetDac(DEVICE_DAC, N2_BIT, 0); Wait(500);//delay for the sensor response time } if((nCO2-nCO2St)>nCO2DeadBand) //CO2 error > 100ppm { cprintf("\nCO2>Set!\n"); //nNwPrsSt=nDryPrs/2*nCO2St/nCO2*2; Mul32(nCO2St,nDryPrs,&nXH,&nXL); Div32(nXH, nXL, nCO2, &nYH,&nYL); nNwPrsSt=nYL; if(nNwPrsSt<30) nNwPrsSt=30; //nN2Add=nN2St-nN2/30*nNwPrsSt/nDryPrs*30; Mul32(nN2,nNwPrsSt,&nXH,&nXL); Div32(nXH, nXL, nDryPrs, &nYH,&nYL); nN2Add=nN2St-nYL; //nN2Add=nN2St-nN2/100*nNwPrsSt/nDryPrs*100; if(nN2Add<0) nN2Add=0;

PAGE 99

89 nN2DC1=nN2Add/2; Mul32(nO2,nNwPrsSt,&nXH,&nXL); Div32(nXH, nXL, nDryPrs, &nYH,&nYL); nO2Add=nO2St-nYL; //nO2Add=nO2St-nO2/15*nNwPrsSt/nDryPrs*15; if(nO2Add<0) nO2Add=0; nO2DC1=nO2Add; if(nO2DC1>=nN2DC1) { nO2DC=1000; Mul32(1000,nN2DC1,&nXH,&nXL); Div32(nXH, nXL, nO2DC1, &nYH,&nYL); nN2DC=nYL; //nN2DC=1000*(nN2DC1/150)/(nO2DC1/150); } else if(nN2DC1>nO2DC1) { nN2DC=1000; Mul32(1000,nO2DC1,&nXH,&nXL); Div32(nXH, nXL, nN2DC1, &nYH,&nYL); nO2DC=nYL; //nO2DC=1000*(nO2DC1/100)/(nN2DC1/100); } //cprintf("P:%d CO2:%d O2:%d N2:%d WV:%d NewP:%d N2Add:%d O2Add:%d N2DC%d O2DC:%d\n", //nDryPrs, nCO2, nO2, nN2, nWV, nNwPrsSt, nN2Add, nO2Add, nN2DC, nO2DC); //pump down till CO2 reaches set point PIO_WriteBit(PIO_1, 0, PUMP_BIT, ON); PIO_WriteBit(PIO_1, 0, VLVE_BIT, ON); do { //if(peekc()) HandleSerialCmd(); CollectData(); }while(nDryPrs-nNwPrsSt>0); PIO_WriteBit(PIO_1, 0, VLVE_BIT, OFF); PIO_WriteBit(PIO_1, 0, PUMP_BIT, OFF); //add O2 till O2 reaches set point//read CO2 PIO_SetDac(DEVICE_DAC, O2_BIT, nO2DC); PIO_SetDac(DEVICE_DAC, N2_BIT, nN2DC); //O2 MFC:500sccm, 5kPa/min, 5V, DC=1000 //nDC=nEO2/100 *100/5 = nEO2*2; do { //if(peekc()) HandleSerialCmd(); CollectData(); nEO2=nO2St-nO2; if(nEO2<250)

PAGE 100

90 { PIO_SetDac(DEVICE_DAC, O2_BIT, (nO2DC/5)*(nEO2/50)); PIO_SetDac(DEVICE_DAC, N2_BIT, (nN2DC/5)*(nEO2/50)); } }while(nO2St-nO2>50);//while((nDryPrsSt-nDryPrs)>0); PIO_SetDac(DEVICE_DAC, O2_BIT, 0); PIO_SetDac(DEVICE_DAC, N2_BIT, 0); Wait(500); } else if(((nCO2St-nCO2)>nCO2DeadBand)&&(bCO2==1)) //CO2 < CO2st { cprintf("CO250);//while((nDryPrsSt-nDryPrs)>0); PIO_SetDac(DEVICE_DAC, CO2_BIT, 0);//nEO2=nO2St-nO2; Wait(500);//delay for the sensor response time } } ADC_1241.c //functions for ADC1231 11/19/2003 #include #include #include "base.h" #include "ADC_1241.h" //initialization and reset int ADC_Ini(int nDevice){ } int ADC_Reset(int nDevice){ SelectDevice(nDevice); ADC_SendByte(0xFE); //ADC_WriteReg(4, 0x0A, 0x59); ADC_WriteReg(4, 0x0B, 0x55);

PAGE 101

91 ADC_WriteReg(4, 0x0C, 0x55); ADC_WriteReg(4, 0x07, 0); ADC_WriteReg(4, 0x08, 0); ADC_WriteReg(4, 0x09, 0); SelectDevice(-1); } //operations on registers int ADC_DumpReg(int nDevice){ cprintf("FSR0: %x\n",ADC_ReadReg(nDevice, 0x0A)); cprintf("FSR1: %x\n",ADC_ReadReg(nDevice, 0x0B)); cprintf("FSR2: %x\n",ADC_ReadReg(nDevice, 0x0C)); } int ADC_ReadReg(int nDevice, int nReg){ int n; SelectDevice(nDevice); ADC_SendByte(0x10|(nReg&0x0F)); ADC_SendByte(0); //(number of regs)-1 Wait(2); n=ADC_ReadByte(); SelectDevice(-1); return(n); } int ADC_WriteReg(int nDevice, int nReg, int nValue){ int nLoopCount, nLoopLimit; int nRead, nTrueFalse; nLoopCount=0; nLoopLimit=100; nTrueFalse=1; do{ SelectDevice(nDevice); ADC_SendByte(0x50|(nReg&0x0F)); ADC_SendByte(0); //(number of regs)-1 ADC_SendByte(nValue); Wait(2); nRead=ADC_ReadReg(nDevice, nReg); // cprintf("%x %x\n", nValue, ADC_ReadReg(nDevice, nReg)); SelectDevice(-1); if(nLoopCount>0) cputs('+');

PAGE 102

92 if(nLoopCount>nLoopLimit) { cprintf("\n Error occoured when writing Reg %d of Device %d!\n", nReg,nDevice); nTrueFalse=0; return(nTrueFalse); } nLoopCount++; }while(nRead!=nValue); return(nTrueFalse); } unsigned int ADC_GetADC(int nDevice){ unsigned int nADC, u2, u1, u0; /* int nMux; ADC_Reset(nDevice); ADC_WriteReg(nDevice, 0, nPGA); if(nSigType==0) //single-ended nMux=(nChannel<<4)|0x08; if(nSigType==1) //differential nMux=(nChannel<<5)|(nChannel*2+1); ADC_WriteReg(nDevice, 1, nMux); */ SelectDevice(nDevice); ADC_SendByte(1); u2=ADC_ReadByte(); u1=ADC_ReadByte(); u0=ADC_ReadByte(); nADC=(u2<<8)|u1; SelectDevice(-1); // cprintf("%d ", nADC); return(nADC); } unsigned int ADC_GetADCLSB(int nLSB, int nDevice){ unsigned int u2, u1, u0, uResult; nLSB&=0x07; do { u0=ADC_ReadReg(2,nDevice); // if(u0&0x80) printf("\n!!!%x!!!\n", u0); } while(u0 & 0x80); // wait for DRDY#

PAGE 103

93 SelectDevice(nDevice); //CS=0; ADC_SendByte(0xFC); // DSYNC command Wait(2); ADC_SendByte(1); // RDATA command Wait(2); u2=ADC_ReadByte(); // high byte u1=ADC_ReadByte(); // mid byte u0=ADC_ReadByte(); // low byte SelectDevice(-1); //CS=-1; // cprintf("%x:%x:%x (%d)\n", u2, u1, u0, nLSB); uResult = u2<<(16-nLSB); // cprintf(" %x\n", uResult); uResult |= u1<<(8-nLSB); // cprintf(" %x\n", uResult); uResult |= u0>>nLSB; // cprintf(" %x\n", uResult); // cprintf(" %x",uResult); // cprintf(" %x %x:%x:%x\n\n", uResult, u2, u1, u0); return(uResult); } unsigned int ADC_GetAveADC(int nDevice, int nCountLimit){ int n0, n1, nSum,nCount; nSum=0; nCount=0; // n0=ADC_GetADCLSB(7,nDevice); n0=ADC_GetADC(nDevice); for(nCount=1; nCount
PAGE 104

94 //Wait(20); } //putc('\n'); return(n0+nSum/nCountLimit); } int ADC_GetDiffVoltage(int nDevice, int nChannel, int nPGA){ int nADC, nMux; SelectDevice(nDevice); nMux=(nChannel<<5)|(nChannel*2+1); ADC_WriteReg(nDevice, 1, nMux); ADC_WriteReg(nDevice, 0, nPGA); nADC=ADC_GetAveADC(nDevice, 16); //nADC=ADC_GetADC(nDevice); return(nADC); } int ADC_GetSingleEndVoltage(int nDevice, int nChannel, int nPGA){ int nADC, nMux; SelectDevice(nDevice); nMux=(nChannel<<4)|0x08; ADC_WriteReg(nDevice, 1, nMux); ADC_WriteReg(nDevice, 0, nPGA); //nADC=ADC_GetAveADC(nDevice, 16); nADC=ADC_GetADC(nDevice); //return(nADC>>6); return(nADC); } int ADC_SendByte(int n){ /* int k; // cprintf("<%x> ", bData); SCL=1; SDO=1; for(k=7; k>=0; k--) { SDO=n & (1<
PAGE 105

95 SCL=1; Nop(); Nop(); SCL=0; Nop(); Nop(); SCL=1; // Nop(); } SDO=1; // putc('\n'); */ #asm DPTRAST movx a, @dptr lcall sendbyte #endasm } int ADC_ReadByte(void){ #asm lcall readbyte mov PRL, a mov PRH, #0 #endasm } void AsmUtil(){ #asm sendbyte: setb _SCL mov C, acc.7 mov _SDO, C lcall pulse mov C, acc.6 mov _SDO, C lcall pulse mov C, acc.5 mov _SDO, C lcall pulse mov C, acc.4 mov _SDO, C lcall pulse mov C, acc.3 mov _SDO, C lcall pulse

PAGE 106

96 mov C, acc.2 mov _SDO, C lcall pulse mov C, acc.1 mov _SDO, C lcall pulse mov C, acc.0 mov _SDO, C lcall pulse ret readbyte: setb _SCL mov C, _SDI mov acc.7, C lcall pulse mov C, _SDI mov acc.6, C lcall pulse mov C, _SDI mov acc.5, C lcall pulse mov C, _SDI mov acc.4, C lcall pulse mov C, _SDI mov acc.3, C lcall pulse mov C, _SDI mov acc.2, C lcall pulse mov C, _SDI mov acc.1, C lcall pulse mov C, _SDI mov acc.0, C lcall pulse ret pulse: setb _SCL lcall delay clr _SCL lcall delay setb _SCL ret

PAGE 107

97 delay: mov r0, #0 djnz r0, $ ret #endasm } PIO.c //PIO.C: functions for PIO 11/29/2003 //#include #include #include "base.h" #include "PIO.h" int PIO_ReadTemp(BYTE bDevice, BYTE bPort, BYTE bBit){ int nTemp1,nTemp2,n,k,nCntr; //EA=0; nCntr=0; // do{ nCntr++; bPort &= 3; bBit &= 7; SelectDevice(bDevice); PIO_WriteWord(0xC0|(bPort<<4)|bBit); for(n=0; n<20000; n++) k++; nTemp1=PIO_GetResponse(); SelectDevice(-1); // EA=1; /* SelectDevice(bDevice); PIO_WriteWord(0xC0|(bPort<<4)|bBit); for(n=0; n<20000; n++) k++; nTemp1=PIO_GetResponse(); SelectDevice(-1); */ // }while((nTemp1!=nTemp2)&&(nCntr<10)); return(nTemp1); } void PIO_WriteBit(BYTE bDevice, BYTE bPort, BYTE bBit, int bValue){ SelectDevice(bDevice);

PAGE 108

98 PIO_WriteWord((bValue<<8)|(bPort<<4)|bBit); SelectDevice(-1); } int PIO_ReadPort(BYTE bDevice, BYTE bPort){ int nResponse; SelectDevice(bDevice); PIO_WriteWord(0x80|(bPort<<4)); nResponse=(PIO_GetResponse()&0xFF); SelectDevice(-1); return(nResponse); } void PIO_WriteWordTo(BYTE bDevice, UINT uData){ // cprintf("[%x, %x] ", bDevice, bData); SelectDevice(bDevice); PIO_WriteWord(uData); SelectDevice(-1); } void PIO_WritePort(BYTE bDevice, BYTE bPort, int bValue){ SelectDevice(bDevice); PIO_WriteWord((bValue<<6)|(bPort<<4)|0x0F); SelectDevice(-1); } void PIO_SetDC(BYTE bDevice, BYTE bPort, BYTE bBit, int nDC){ SelectDevice(bDevice); PIO_WriteWord((nDC<<8)|0x40|(bPort<<4)|bBit); SelectDevice(-1); } void PIO_WriteWord(int bValue){ int k; SCL=1; SDO=1; for(k=15; k>=0; k--) { SDO=bValue & (1<
PAGE 109

99 Nop(); SCL=0; Nop(); SCL=1; } SDO=1; } int PIO_GetResponse(){ int n, nResponse; SCL=1; // now read response nResponse=0; for(n=15; n>=0; n--) { Nop(); SCL=0; Nop(); if(SDI) nResponse |= 1<>8) | ((nChannel&0x06)<<3) | 0x40; // 01xx:0xdd if(nChannel&1) nWordLow |= 0x04; /*cprintf("ch = %x\n", nChannel); cprintf("data = %x\n", nData); cprintf("device = %x\n", nDevice); cprintf("low = %x\n", nWordLow); cprintf("high = %x\n", nWordHigh); cprintf("arg = %x\n", (nWordHigh<<8) | nWordLow);

PAGE 110

100 */ PIO_WriteWordTo(nDevice, (nWordHigh<<8) | nWordLow); // ourput dac : 01cc 0cdd dddd:dddd (c: channel, d:data) /* WriteWordTo(0x0042, nDevice); // ch 0 = 2.5V WriteWordTo(0x0046, nDevice); // ch 1 = 2.5V WriteWordTo(0x0052, nDevice); // ch 2 = 2.5V WriteWordTo(0x0056, nDevice); // ch 3 = 2.5V WriteWordTo(0x0062, nDevice); // ch 4 = 2.5V WriteWordTo(0x0066, nDevice); // ch 5 = 2.5V WriteWordTo(0x0072, nDevice); // ch 6 = 2.5V WriteWordTo(0x0076, nDevice); // ch 7 = 2.5V */ } eeprom.c //eeprom.c: functions for eeprom 12/01/03 //#include #include #include "base.h" #include "eeprom.h" void EE_WriteByte(BYTE bDataAddress, BYTE bData){ //bData=0x64; //cprintf("Writiting byte...\n"); SelectDevice(EEPROM); EE_Start(); //cprintf("WriteByte Device Address\n"); _WriteByte(0xA0); //cprintf("WriteByte bDataAddress %d\n", bDataAddress); _WriteByte(bDataAddress); //cprintf("WriteByte bData %d\n", bData); _WriteByte(bData); EE_Stop(); SelectDevice(-1); } int EE_ReadByte(BYTE bDataAddress){ int nRead; //cprintf("Reading byte...\n");

PAGE 111

101 SelectDevice(EEPROM); EE_Start(); //cprintf("WriteByte Device Address \n"); _WriteByte(0xA0); //cprintf("WriteByte bDataAddress %d \n", bDataAddress); _WriteByte(bDataAddress); EE_Start(); _WriteByte(0xA1); nRead=_ReadByte(); //cprintf("ReadByte:%d ", nRead); EE_Stop(); SelectDevice(-1); return(nRead); } void EE_WriteWord(BYTE bDataAddress, int nData){ int nResult, nLow, nHigh; nLow=nData&0xFF; nHigh=(nData>>8)&0xFF; EE_WriteByte(bDataAddress, nLow); Wait(10); EE_WriteByte(bDataAddress+1, nHigh); //cprintf("%d %d %d\n",bDataAddress, nData, EE_ReadWord(bDataAddress)); } int EE_ReadWord(BYTE bDataAddress){ int nResult, nLow, nHigh; nLow=EE_ReadByte(bDataAddress); nHigh=EE_ReadByte(bDataAddress+1); nResult=(nHigh<<8)|nLow; return(nResult); } void EE_Start(){ SDA=1; SCL=1; Nop(); SDA=0; Nop(); SCL=0;

PAGE 112

102 } void EE_Stop(){ SDA=0; SCL=1; Nop(); SDA=1; Nop(); SCL=0; } int _ReadByte(){ int n, nData, nACK; nData=0; SDA=1; for(n=7;n>=0;n--) { SCL=1; if(SDA) nData|=(1<=0;n--) {

PAGE 113

103 SCL=0; SDA=bData&(1< #include #include "base.h" #include "SystemTime.h" #define TICK_PER_SECOND 244 int ngCounter, ngTick, ngSec, ngMin, ngHour; void Time_InitSystemTime(){ TMOD=0xF0; ET0=1; TR0=1; PS=1; EA=1; ngCounter=0; ngTick=0; ngSec=0; ngMin=0; ngHour=0; } void interrupt(0x0B) Time_T0Isr(void){

PAGE 114

104 int nMinTick; ngCounter++; if(ngCounter>TICK_PER_SECOND) { ngTick++; ngSec=ngTick%60; nMinTick=ngTick/60; ngMin=nMinTick%60; ngHour=ngMin/60; // cprintf("ngCounter:%d ngTick:%d ngSec:%d ngMin:%d ngHour%d\n", // ngCounter,ngTick,ngSec,ngMin,ngHour); ngCounter=0; } } int Time_GetSec(){ return(ngSec); } int Time_GetMin(){ return(ngMin); } int Time_GetHour(){ return(ngHour); } memmap.asm ; ------------READS51 generated header -------------; module : C:\Rigel\Reads51\Jobs\Mib\Base_Pio\memmap.asm ; created : 18:22:11, Thursday, May 02, 2002 ; ----------------------------------------------------public _bgDeviceLo, _bgDeviceHi xseg at 0xFF80 _bgDeviceLo: ds 1 end xseg at 0xFFC0 _bgDeviceHi: ds 1 end

PAGE 115

105 base.h //definitions and prototypes for funtions 11/19/2003 //constants #define TRUE 1 #define FALSE 0 #define ON 0 #define OFF 1 #define CS_DISABLE -1 #define BYTE unsigned char //(unsigned, one byte long) #define UINT unsigned int //definitions #define SCL P1_6 #define SDO P1_4 //MOSI: master out slave in, SDI on schematic (write to peripherals) #define SDI P1_5 //MISO: master in slave out, SDO on schematic (read from peripherals) //asm #define _SCL P1.6 #define _SDO P1.4 #define _SDI P1.5 //device number #define ADC_0 0 #define ADC_1 1 #define ADC_2 2 #define ADC_3 3 #define ADC_4 4 #define ADC_5 5 #define ADC_6 6 #define ADC_7 7 #define PIO_0 8 #define PIO_1 9 #define PIO_T0 10 #define PIO_T1 11 #define DEVICE_DAC 12 #define EEPROM 15 //control bit #define PUMP_BIT 1 #define VLVE_BIT 2 #define HUMI_BIT 3

PAGE 116

106 #define TE_BIT 4 #define N2_BIT 0 #define O2_BIT 1 #define CO2_BIT 2 //prototypes //initialization void InitSerial(); // void SelectDevice(int nDevice); //reading from sensors void CollectData(); int GetO2(int nDevice, int nUnit, int nPGA); int GetCO2(int nDevice, int nUnit, int nPGA); int GetRH(int nDevice, int nUnit, int nPGA); int GetWeight(int nDevice, int nUnit, int nPGA, int nCountLimit); //int GetWeight(int nDevice, int nUnit); //int GetPressure(int nDevice, int nChannel); //int GetTemp(int nChannel); //Control void GetSetPoints(); void CalSetPoints(); void GasControl(int bCO2); void PrsControl(); //misc void Wait(int n); void Nop(void); int GetDec(void); void HandleCommand(char cCmd); void HandleSerialCmd(); void Abs(int n); int Max(int x1, int x2, int x3); int MaxIndex(int x1, int x2, int x3, int x4); void Mul32(uint uX, uint uY, uint *puRH, uint *puRL); void Div32(uint uXH, uint uXL, uint uDiv, uint *puRH, uint *puRL); //void Serial_Isr(void); ADC_1241.h //definitions and prototypes for ADC funtions 11/19/2003 //prototypes //initialization and reset int ADC_Ini(int nDevice); int ADC_Reset(int nDevice);

PAGE 117

107 //operations on registers int ADC_DumpReg(int nDevice); int ADC_ReadReg(int nDevice, int nReg); int ADC_WriteReg(int nDevice, int nReg, int nValue); unsigned int ADC_GetADC(int nDevice); unsigned int ADC_GetADCLSB(int nLSB, int nDevice); unsigned int ADC_GetAveADC(int nDevice); int ADC_GetDiffVoltage(int nDevice, int nChannel,int PGA); int ADC_GetSingleEndVoltage(int nDevice, int nChannel, int nPGA); int ADC_SendByte(int n); int ADC_ReadByte(void); //misc void AsmUtil(void); PIO.h //definitions and prototypes for PIO funtions 11/29/2003 int PIO_ReadTemp(BYTE nDevice, BYTE nPort, BYTE nBit); void PIO_WriteBit(BYTE nDevice, BYTE nPort, BYTE nBit, BYTE nValue); int PIO_ReadPort(BYTE nDevice, BYTE nPort); void PIO_WritePort(BYTE nDevice, BYTE nPort, BYTE nValue); int PIO_ReadTemp(BYTE nDevice, BYTE nPort, BYTE nBit); void PIO_SetDC(BYTE bDevice, BYTE bPort, BYTE bBit, int nDC); void PIO_SetDac(int nDevice, int nChannel, int nData); void PIO_WriteWordTo(BYTE bDevice, UINT uData); void PIO_WriteWord(BYTE nValue); //int PIO_GetResponseFrom(BYTE nDevice); int PIO_GetResponse(); eeprom.h //definitions and prototypes for eeprom funtions 12/01/2003 #define SDA P1_4 #define _SDA P1.4 void EE_WriteByte(BYTE bDataAddress, BYTE bData); int EE_ReadByte(BYTE bDataAddress); void EE_WriteWord(BYTE bDataAddress, int nData); int EE_ReadWord(BYTE bDataAddress); void EE_Start(); void EE_Stop(); int _ReadByte();

PAGE 118

108 void _WriteByte(BYTE bData); SystemTime.h //definitions and prototypes for system time funtions 11/19/2003 void Time_InitSystemTime(); void Time_T0Isr(void); int Time_GetSec(); int Time_GetMin(); int Time_GetHour();

PAGE 119

APPENDIX B PC CODE databaseview.cpp // database_01View.cpp : implementation of the CDatabase_01View class // #include "stdafx.h" #include "database_01.h" #include "database_01Set.h" #include "OScopeCtrl.h" #include "database_01Doc.h" #include "database_01View.h" #include "initdata.h" #include "mscomm.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define comInputModeBinary 1 #define comInputModeText 0 #define comEvReceive 2 #define DataLength2 5 #define DataLength1 11 #define POINTS_X_RANGE 200 #define DEMO_MAX_GRAPHS 16 COLORREF DefaultGraphColors[DEMO_MAX_GRAPHS] = {RGB(255, 0, 0), RGB(0, 255, 0), RGB(0, 0, 255), RGB(255, 255, 0), RGB(0, 255, 255), 32768, 128, 8388736, 8421440, 12615808, 8421504, 33023, 16711935, 12632256, 32896, RGB(0, 0, 0)}; ///////////////////////////////////////////////////////////////////////////// 109

PAGE 120

110 // CDatabase_01View IMPLEMENT_DYNCREATE(CDatabase_01View, CRecordView) BEGIN_MESSAGE_MAP(CDatabase_01View, CRecordView) //{{AFX_MSG_MAP(CDatabase_01View) ON_COMMAND(IDC_RECORD_ADD, OnRecordAdd) //ON_BN_CLICKED(IDC_BUTTON_ADD, OnButtonAdd) ON_WM_SIZE() ON_WM_CREATE() ON_WM_CTLCOLOR() ON_WM_TIMER() ON_BN_CLICKED(IDC_BUTTON_SETPOINT, OnButtonSetpoint) ON_EN_CHANGE(IDC_CO2_SET, OnChangeCo2Set) ON_EN_CHANGE(IDC_OXYGEN_SET, OnChangeOxygenSet) ON_EN_CHANGE(IDC_PRESSURE_SET, OnChangePressureSet) ON_EN_CHANGE(IDC_RH_SET, OnChangeRhSet) ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop) ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart) //}}AFX_MSG_MAP // Standard printing commands ON_COMMAND(ID_FILE_PRINT, CRecordView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CRecordView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRecordView::OnFilePrintPreview) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDatabase_01View construction/destruction CDatabase_01View::CDatabase_01View() : CRecordView(CDatabase_01View::IDD) { //{{AFX_DATA_INIT(CDatabase_01View) //m_pSet = NULL; m_dPrs = 0.0f; m_dRH = 0.0f; m_dTemp = 0.0f; m_dCO2 = 0.0f; m_dO2 = 0.0f; m_dLght = 0.0; m_dWght = 0.0; m_Cmd = _T(""); m_CmEvnt = 0; m_dPrsSt = 0.0; m_dO2St = 0.0;

PAGE 121

111 m_dCO2St = 0.0; m_dRHSt = 0.0; m_sResp = _T(""); m_bFlag=1; //}}AFX_DATA_INIT m_bAddMode = FALSE; m_OScopeCtrl_Temp.m_sTitle = "Temp"; m_OScopeCtrl_Temp.m_crTextColor=m_OScopeCtrl_Temp.m_crTempColor; m_OScopeCtrl_RH.m_sTitle = "RH"; m_OScopeCtrl_RH.m_crTextColor=m_OScopeCtrl_RH.m_crRHColor; m_OScopeCtrl_Prs.m_sTitle = "Pressure"; m_OScopeCtrl_Prs.m_crTextColor=m_OScopeCtrl_Prs.m_crPrsColor; m_OScopeCtrl_CO2.m_sTitle = "CO2"; m_OScopeCtrl_CO2.m_crTextColor=m_OScopeCtrl_CO2.m_crCO2Color; m_OScopeCtrl_O2.m_sTitle = "O2"; m_OScopeCtrl_O2.m_crTextColor=m_OScopeCtrl_O2.m_crO2Color; m_OScopeCtrl_Wght.m_sTitle = "Weight"; m_OScopeCtrl_Wght.m_crTextColor=m_OScopeCtrl_Wght.m_crWghtColor; // graph_count = 0; } CDatabase_01View::~CDatabase_01View() { } void CDatabase_01View::DoDataExchange(CDataExchange* pDX) { CRecordView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDatabase_01View) DDX_Control(pDX, IDC_BUTTON_ADD, m_bStart); DDX_Control(pDX, IDC_MSCOMM1, m_Comm1); DDX_Control(pDX, IDC_MSCOMM2, m_Comm2); DDX_Text(pDX, IDC_PRESSURE2, m_dPrs); DDX_Text(pDX, IDC_RH2, m_dRH); DDX_Text(pDX, IDC_TEMP2, m_dTemp); DDX_Text(pDX, IDC_CO2, m_dCO2); DDX_Text(pDX, IDC_OXYGEN, m_dO2);

PAGE 122

112 DDX_Text(pDX, IDC_LIGHT, m_dLght); DDX_Text(pDX, IDC_WEIGHT, m_dWght); DDX_Text(pDX, IDC_CMD, m_Cmd); DDX_Text(pDX, IDC_CMEVNT, m_CmEvnt); DDX_Text(pDX, IDC_PRESSURE_SET, m_dPrsSt); DDV_MinMaxDouble(pDX, m_dPrsSt, 0., 102.); DDX_Text(pDX, IDC_OXYGEN_SET, m_dO2St); DDV_MinMaxDouble(pDX, m_dO2St, 0., 20.); DDX_Text(pDX, IDC_CO2_SET, m_dCO2St); DDV_MinMaxDouble(pDX, m_dCO2St, 0., 5000.); DDX_Text(pDX, IDC_RH_SET, m_dRHSt); DDV_MinMaxDouble(pDX, m_dRHSt, 0., 100.); DDX_Text(pDX, IDC_RESP, m_sResp); //}}AFX_DATA_MAP } BOOL CDatabase_01View::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CRecordView::PreCreateWindow(cs); } void CDatabase_01View::OnInitialUpdate() { //m_Comm2.SetCommPort(2); //m_Comm2.SetSettings("57600,N,8,1"); m_pSet = &GetDocument()->m_database_01Set; m_pSet->Open(); if(!m_pSet->IsEOF()) m_pSet->MoveLast(); m_dTemp=m_pSet->m_dTemp; m_dLght=m_pSet->m_dLght; m_dWght=m_pSet->m_dWght; m_dRH=m_pSet->m_dRH; m_dPrs=m_pSet->m_dPrs; m_dCO2=m_pSet->m_dCO2; m_dO2=m_pSet->m_dO2; m_dRHSt=m_pSet->m_dRHSt; m_dPrsSt=m_pSet->m_dPrsSt; m_dCO2St=m_pSet->m_dCO2St; m_dO2St=m_pSet->m_dO2St; UpdateData(FALSE); CRecordView::OnInitialUpdate();

PAGE 123

113 GetParentFrame()->RecalcLayout(); ResizeParentToFit(); CRect rect; //Graph of Temperature GetDlgItem(IDC_GRAPH_TEMP)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_Temp.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_Temp.SetRange(0, 50, 0) ; m_OScopeCtrl_Temp.SetYUnits("T (C)") ; m_OScopeCtrl_Temp.SetXUnits("Time") ; m_OScopeCtrl_Temp.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_Temp.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_Temp.SetPlotColor(m_OScopeCtrl_Temp.m_crTempColor) ; m_OScopeCtrl_Temp.m_dPreviousX = rect.left -10; //Graph of RH GetDlgItem(IDC_GRAPH_RH)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_RH.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_RH.SetRange(0, 100, 0) ; m_OScopeCtrl_RH.SetYUnits("RH (%)") ; m_OScopeCtrl_RH.SetXUnits("Time") ; m_OScopeCtrl_RH.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_RH.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_RH.SetPlotColor(m_OScopeCtrl_RH.m_crRHColor) ; m_OScopeCtrl_RH.m_dPreviousX = rect.left -10; //Graph of Pressure GetDlgItem(IDC_GRAPH_PRS)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_Prs.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_Prs.SetRange(0, 100, 0) ; m_OScopeCtrl_Prs.SetYUnits("P (kPa)") ; m_OScopeCtrl_Prs.SetXUnits("Time") ; m_OScopeCtrl_Prs.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_Prs.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_Prs.SetPlotColor(m_OScopeCtrl_Prs.m_crPrsColor) ; m_OScopeCtrl_Prs.m_dPreviousX = rect.left -195; //Graph of CO2 GetDlgItem(IDC_GRAPH_CO2)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_CO2.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_CO2.SetRange(0, 500, 0) ;

PAGE 124

114 m_OScopeCtrl_CO2.SetYUnits("CO2 (ppm)") ; m_OScopeCtrl_CO2.SetXUnits("Time") ; m_OScopeCtrl_CO2.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_CO2.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_CO2.SetPlotColor(m_OScopeCtrl_CO2.m_crCO2Color) ; m_OScopeCtrl_CO2.m_dPreviousX = rect.left -10; //Graph of O2 GetDlgItem(IDC_GRAPH_O2)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_O2.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_O2.SetRange(0, 20, 0) ; m_OScopeCtrl_O2.SetYUnits("O2 (kPa)") ; m_OScopeCtrl_O2.SetXUnits("Time") ; m_OScopeCtrl_O2.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_O2.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_O2.SetPlotColor(m_OScopeCtrl_O2.m_crO2Color) ; m_OScopeCtrl_O2.m_dPreviousX = rect.left -200; //Graph of Weight GetDlgItem(IDC_GRAPH_WGHT)->GetWindowRect(rect) ; ScreenToClient(rect) ; m_OScopeCtrl_Wght.Create(WS_VISIBLE | WS_CHILD, rect, this) ; m_OScopeCtrl_Wght.SetRange(0, 3000, 0) ; m_OScopeCtrl_Wght.SetYUnits("W (g)") ; m_OScopeCtrl_Wght.SetXUnits("Time") ; m_OScopeCtrl_Wght.SetBackgroundColor(RGB(125, 125, 125)) ; m_OScopeCtrl_Wght.SetGridColor(RGB(0, 192, 255)) ; m_OScopeCtrl_Wght.SetPlotColor(m_OScopeCtrl_Wght.m_crWghtColor) ; m_OScopeCtrl_Wght.m_dPreviousX = rect.left -10; // Creates a 12-point-Courier-font // m_Font.CreatePointFont(120, _T("Courier")); m_Font.CreateFont(24, // Height 12, // Width 0, // Escapement 0, // Orientation FW_BOLD, // Weight FALSE, // Italic FALSE, // Underline 0, // StrikeOut ANSI_CHARSET, // CharSet OUT_DEFAULT_PRECIS, // OutPrecision CLIP_DEFAULT_PRECIS, // ClipPrecision DEFAULT_QUALITY, // Quality

PAGE 125

115 DEFAULT_PITCH | FF_SWISS, // PitchAndFamily "Arial"); // Facename // Without a member variable GetDlgItem(IDC_TITLE)->SetFont(&m_Font); m_textColor = RGB(255,0,0); m_backColor = ::GetSysColor(COLOR_GRAYTEXT); m_backBrush.CreateSolidBrush(m_backColor); CRecordView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); } ///////////////////////////////////////////////////////////////////////////// // CDatabase_01View printing BOOL CDatabase_01View::OnPreparePrinting(CPrintInfo* pInfo) { // default preparation return DoPreparePrinting(pInfo); } void CDatabase_01View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add extra initialization before printing } void CDatabase_01View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: add cleanup after printing } ///////////////////////////////////////////////////////////////////////////// // CDatabase_01View diagnostics #ifdef _DEBUG void CDatabase_01View::AssertValid() const { CRecordView::AssertValid(); } void CDatabase_01View::Dump(CDumpContext& dc) const {

PAGE 126

116 CRecordView::Dump(dc); } CDatabase_01Doc* CDatabase_01View::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDatabase_01Doc))); return (CDatabase_01Doc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CDatabase_01View database support CRecordset* CDatabase_01View::OnGetRecordset() { return m_pSet; } ///////////////////////////////////////////////////////////////////////////// // CDatabase_01View message handlers void CDatabase_01View::OnRecordAdd() { // If already in add mode, then complete previous new record if (m_bAddMode) OnMove(ID_RECORD_FIRST); // CString strCurrentCourse = m_pSet->m_CourseID; m_pSet->AddNew(); m_pSet->SetFieldNull(NULL, FALSE); // m_pSet->SetFieldNull(&(m_pSet->m_CourseID), FALSE); // m_pSet->m_CourseID = strCurrentCourse; m_bAddMode = TRUE; // m_ctlSection.SetReadOnly(FALSE); UpdateData(FALSE); } BOOL CDatabase_01View::OnMove(UINT nIDMoveCommand) { if (m_bAddMode) { if (!UpdateData()) return FALSE; TRY {

PAGE 127

117 m_pSet->Update(); } CATCH(CDBException, e) { AfxMessageBox(e->m_strError); return FALSE; } END_CATCH m_pSet->Requery(); UpdateData(FALSE); // m_ctlSection.SetReadOnly(TRUE); m_bAddMode = FALSE; return TRUE; } else { return CRecordView::OnMove(nIDMoveCommand); } } BEGIN_EVENTSINK_MAP(CDatabase_01View, CRecordView) //{{AFX_EVENTSINK_MAP(CDatabase_01View) ON_EVENT(CDatabase_01View, IDC_MSCOMM1, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE) ON_EVENT(CDatabase_01View, IDC_MSCOMM2, 1 /* OnComm */, OnOnCommMscomm2, VTS_NONE) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() void CDatabase_01View::OnOnCommMscomm2() { int m,n,temp,i,nEvent;; int nDataCount; double dValue; m_CmEvnt=m_Comm2.GetCommEvent(); //AfxMessageBox("CommEvent"); UpdateData(FALSE); nDataCount=0; switch(m_CmEvnt) { case comEvReceive: // Wait(100); //AfxMessageBox("Receive some data");

PAGE 128

118 m_Count=m_Comm2.GetInBufferCount(); B=m_Comm2.GetInput(); m_Cmd+=B.bstrVal; //UpdateData(FALSE); UpdateData(FALSE); m_Comm2.SetPortOpen(FALSE); //AfxMessageBox("Port Closed"); // m_Comm.SetRThreshold(m_Count); nDataCount = m_Count/DataLength2; for(m=0;mpvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } if((dValue/16>0)&&(dValue/16<100)) m_dTemp = dValue/16; m_pSet->AddNew(); m_pSet->m_tTime = CTime::GetCurrentTime(); m_pSet->m_dTemp = m_dTemp; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dRH = dValue; if((dValue>0)&&(dValue<100)) m_dRH = dValue; m_pSet->m_dRH = m_dRH; m++; dValue=0; for(n=0;n<5;n++) {

PAGE 129

119 temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; // m_Value=1089.5-0.0781*dValue; } //m_pSet->m_dPrs = dValue/10; if((dValue>0)&&(dValue<1000)) m_dPrs = dValue/5; m_pSet->m_dPrs = m_dPrs; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dCO2 = dValue/100; if((dValue>0)&&(dValue<10000)) m_dCO2 = dValue/10; m_pSet->m_dCO2 = m_dCO2; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dO2 = dValue/100; if((dValue>0)&&(dValue<10000)) m_dO2 = dValue/500; m_pSet->m_dO2 = m_dO2; //m_pSet->Update(); m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; }

PAGE 130

120 //m_pSet->m_dO2 = dValue/100; //m_dLght = dValue*0.164; if((dValue>0)&&(dValue<10000)) m_dLght = dValue*0.1635; m_pSet->m_dLght = m_dLght; //m_pSet->Update(); m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dO2 = dValue/100; if((dValue>0)&&(dValue<20000)) m_dWght = dValue*0.08; m_pSet->m_dWght = m_dWght; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dRH = dValue; if((dValue>0)&&(dValue<100)) m_dRHSt = dValue; m_pSet->m_dRHSt = m_dRHSt; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; // m_Value=1089.5-0.0781*dValue; } //m_pSet->m_dPrs = dValue/10; if((dValue>0)&&(dValue<1000)) m_dPrsSt = dValue/5; m_pSet->m_dPrsSt = m_dPrsSt;

PAGE 131

121 m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dCO2 = dValue/100; if((dValue>0)&&(dValue<5000)) m_dCO2St = dValue/10; m_pSet->m_dCO2St = m_dCO2St; m++; dValue=0; for(n=0;n<5;n++) { temp=((unsigned char *)B.parray->pvData)[m*DataLength2+n]; dValue=10*dValue + temp 48; } //m_pSet->m_dO2 = dValue/100; if((dValue>0)&&(dValue<10000)) m_dO2St = dValue/500; m_pSet->m_dO2St = m_dO2St; m_pSet->Update(); m++; } break; } m_OScopeCtrl_Temp.AppendPoint(m_dTemp); m_OScopeCtrl_RH.AppendPoint(m_dRH); m_OScopeCtrl_Prs.AppendPoint(m_dPrs); m_OScopeCtrl_CO2.AppendPoint(m_dCO2); m_OScopeCtrl_O2.AppendPoint(m_dO2); m_OScopeCtrl_Wght.AppendPoint(m_dWght); UpdateData(FALSE); } void CDatabase_01View::OnOnCommMscomm1() { int m,n,temp; int dataCount;

PAGE 132

122 float m_Temp, m_Value; AfxMessageBox("CommEvent"); dataCount=0; switch(m_Comm1.GetCommEvent()) { case comEvReceive: // Wait(100); m_Count=m_Comm1.GetInBufferCount(); B=m_Comm1.GetInput(); AfxMessageBox("Receive some data"); UpdateData(FALSE); // m_Comm.SetRThreshold(m_Count); dataCount = m_Count/DataLength1; for(m=0;mpvData)[m*DataLength1+n]; if(n<5); else m_Temp=10*m_Temp + temp 48; } m_pSet->AddNew(); m_pSet->m_dPrs = m_Temp; m_pSet->Update(); } break; } m_Comm1.SetPortOpen(FALSE); } void CDatabase_01View::OnSize(UINT nType, int cx, int cy) { CRecordView::OnSize(nType, cx, cy); // CView::OnSize(nType, cx, cy); // graph_wnd.MoveWindow(0, 0, cx, cy);

PAGE 133

123 } int CDatabase_01View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CRecordView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here CWnd* pWnd = GetDlgItem(IDC_GRAPH); // COleControl* pWnd = (COleControl*)GetDlgItem(IDC_GRAPH); CRect rect; // GetDlgItem(IDC_GRAPH)->GetWindowRect(rect) ; // ScreenToClient(rect) ; CRect lDrawRect; lDrawRect.top = rect.bottom/2 ; lDrawRect.left = rect.right/2; lDrawRect.bottom = rect.bottom; lDrawRect.right = rect.right; // graph_wnd.Create(_T("Graph Window"), rect, this, 11000); return 0; } HBRUSH CDatabase_01View::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CRecordView::OnCtlColor(pDC, pWnd, nCtlColor); switch (pWnd->GetDlgCtrlID()) { case IDC_TITLE: // pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(RGB(255,0,0)); // change the text color // pDC->SetBkColor(m_backColor); return (HBRUSH)m_backBrush.GetSafeHandle(); break; } return hbr; } void CDatabase_01View::OnTimer(UINT nIDEvent) {

PAGE 134

124 // TODO: Add your message handler code here and/or call default //AfxMessageBox("TimeOut"); if(m_bFlag==1) CollectData(); CRecordView::OnTimer(nIDEvent); } void CDatabase_01View::OnButtonSetpoint() { CString temp; int nPort,m,i; BOOL bPortOpen; nPort = m_Comm2.GetCommPort(); if(nPort!=2) m_Comm2.SetCommPort(2); m_Comm2.SetSettings("57600,N,8,1"); bPortOpen = m_Comm2.GetPortOpen(); if(!bPortOpen) m_Comm2.SetPortOpen(TRUE); m_Comm2.SetInputLen(0); m_Comm2.SetInputMode(comInputModeBinary); m_Comm2.SetRThreshold(5); m_Comm2.GetInput(); UpdateData(TRUE); m_Cmd = "C2,"; m_Cmd+= DataConversion((int)m_dPrsSt); m_Comm2.SetOutput(COleVariant(m_Cmd)); //} Wait(20000); m_Cmd = "C1,"; m_Cmd+= DataConversion((int)m_dRHSt); m_Comm2.SetOutput(COleVariant(m_Cmd)); UpdateData(FALSE); B=m_Comm2.GetInput(); m_sResp=B.bstrVal; //if(B.bVal=='C') //{ Wait(20000); m_Cmd = "C3,"; m_Cmd+= DataConversion((int)m_dCO2St); m_Comm2.SetOutput(COleVariant(m_Cmd)); Wait(20000);

PAGE 135

125 m_Cmd = "C4,"; m_Cmd+= DataConversion((int)m_dO2St); m_Comm2.SetOutput(COleVariant(m_Cmd)); UpdateData(FALSE); m_Comm2.SetPortOpen(FALSE); m_bFlag=1; } CString CDatabase_01View::DataConversion(int nData) { CString str; char n0,n1,n2,n3,n4; n4=nData/10000+48; str+=n4; str+=','; n3=(nData%10000)/1000+48; str+=n3; n2=(nData%1000)/100+48; str+=n2; n1=(nData%100)/10+48; str+=n1; n0=nData%10+48; str+=n0; str+=','; //str = n3+ ','+ n2 + n1 + n0 + '0'; return(str); } void CDatabase_01View::Wait(int nLimit) { int i,j; for(i=0;i
PAGE 136

126 void CDatabase_01View::OnChangeOxygenSet() { m_bFlag=0; } void CDatabase_01View::OnChangePressureSet() { m_bFlag=0; } void CDatabase_01View::OnChangeRhSet() { m_bFlag=0; } void CDatabase_01View::CollectData() { SendCommand("A"); } void CDatabase_01View::OnButtonStop() { SendCommand("E0,"); } void CDatabase_01View::OnButtonStart() { SendCommand("E1,"); CRecordView::SetTimer(1,10000,NULL); CollectData(); } void CDatabase_01View::SendCommand(CString sCmd) { int nPort; BOOL bPortOpen; nPort = m_Comm2.GetCommPort(); if(nPort!=2) m_Comm2.SetCommPort(2); m_Comm2.SetSettings("57600,N,8,1"); bPortOpen = m_Comm2.GetPortOpen(); if(!bPortOpen) m_Comm2.SetPortOpen(TRUE);

PAGE 137

127 m_Comm2.SetInputLen(0); m_Comm2.SetInputMode(comInputModeBinary); m_Comm2.SetRThreshold(55); m_Comm2.GetInput(); //UpdateData(TRUE); m_Cmd=sCmd; UpdateData(FALSE); m_Comm2.SetOutput(COleVariant(m_Cmd)); } databaseview.h // ///////////////////////////////////////////////////////////////////////////// //{{AFX_INCLUDES() #include "OScopeCtrl.h" // Added by ClassView #include "mscomm.h" //}}AFX_INCLUDES #if !defined(AFX_DATABASE_01VIEW_H__564D3325_5383_4E4B_8B93_923E1170524B__INCLUDED_) #define AFX_DATABASE_01VIEW_H__564D3325_5383_4E4B_8B93_923E1170524B__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "mscomm.h" //#include "graph\\graphwnd.h" class CDatabase_01Set; class CDatabase_01View : public CRecordView { protected: // create from serialization only CDatabase_01View(); DECLARE_DYNCREATE(CDatabase_01View) public: //{{AFX_DATA(CDatabase_01View) enum { IDD = IDD_DATABASE_01_FORM }; CBitmapButton m_bStart; int m_Count;

PAGE 138

128 CString m_Command; CDatabase_01Set* m_pSet; VARIANT B; CMSComm m_Comm1; CMSComm m_Comm2; double m_dPrs; double m_dRH; double m_dTemp; COLORREF m_textColor; COLORREF m_backColor; CBrush m_backBrush; double m_dCO2; double m_dO2; double m_dLght; double m_dWght; CString m_Cmd; int m_CmEvnt; double m_dPrsSt; double m_dO2St; double m_dCO2St; double m_dRHSt; CString m_sResp; //}}AFX_DATA // Attributes protected: BOOL m_bAddMode; public: CDatabase_01Doc* GetDocument(); /* long AddNewGraph(BOOL bDrawPoints, double x_range); CGraphWnd graph_wnd; long graph_count; long dyn_graph_id; long current_x; */ // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDatabase_01View) public: virtual CRecordset* OnGetRecordset();

PAGE 139

129 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); virtual BOOL OnMove(UINT nIDMoveCommand); protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual void OnInitialUpdate(); // called first time after construct virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); //}}AFX_VIRTUAL // Implementation public: void SendCommand(CString sCmd); void CollectData(); BOOL m_bFlag; void Wait(int nLimit); CString DataConversion(int nData); CFont m_Font; COScopeCtrl m_OScopeCtrl_Temp; COScopeCtrl m_OScopeCtrl_RH; COScopeCtrl m_OScopeCtrl_Prs; COScopeCtrl m_OScopeCtrl_CO2; COScopeCtrl m_OScopeCtrl_O2; COScopeCtrl m_OScopeCtrl_Wght; virtual ~CDatabase_01View(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // Generated message map functions protected: //{{AFX_MSG(CDatabase_01View) afx_msg void OnRecordAdd(); afx_msg void OnOnCommMscomm1(); afx_msg void OnOnCommMscomm2(); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnButtonSetpoint(); afx_msg void OnChangeCo2Set(); afx_msg void OnChangeOxygenSet();

PAGE 140

130 afx_msg void OnChangePressureSet(); afx_msg void OnChangeRhSet(); afx_msg void OnButtonStop(); afx_msg void OnButtonStart(); DECLARE_EVENTSINK_MAP() //}}AFX_MSG DECLARE_MESSAGE_MAP() }; #ifndef _DEBUG // debug version in database_01View.cpp inline CDatabase_01Doc* CDatabase_01View::GetDocument() { return (CDatabase_01Doc*)m_pDocument; } #endif ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_DATABASE_01VIEW_H__564D3325_5383_4E4B_8B93_923E1170524B__INCLUDED_) database_01Set.cpp // database_01Set.cpp : implementation of the CDatabase_01Set class // #include "stdafx.h" #include "database_01.h" #include "database_01Set.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDatabase_01Set implementation IMPLEMENT_DYNAMIC(CDatabase_01Set, CRecordset) CDatabase_01Set::CDatabase_01Set(CDatabase* pdb) : CRecordset(pdb) { //{{AFX_FIELD_INIT(CDatabase_01Set)

PAGE 141

131 m_dTemp = 0; m_dRH = 0; m_dPrs = 0; m_nFields = 12; //}}AFX_FIELD_INIT m_nDefaultType = snapshot; } CString CDatabase_01Set::GetDefaultConnect() { return _T("ODBC;DSN=greenhouse"); } CString CDatabase_01Set::GetDefaultSQL() { return _T("[environment]"); } void CDatabase_01Set::DoFieldExchange(CFieldExchange* pFX) { //{{AFX_FIELD_MAP(CDatabase_01Set) pFX->SetFieldType(CFieldExchange::outputColumn); RFX_Double(pFX, _T("[Temp]"), m_dTemp); RFX_Double(pFX, _T("[RH]"), m_dRH); RFX_Double(pFX, _T("[Pressure]"), m_dPrs); RFX_Double(pFX, _T("[O2]"), m_dO2); RFX_Double(pFX, _T("[CO2]"), m_dCO2); RFX_Double(pFX, _T("[Light]"), m_dLght); RFX_Double(pFX, _T("[Weight]"), m_dWght); RFX_Date(pFX, _T("[Time]"), m_tTime); RFX_Double(pFX, _T("[RHSt]"), m_dRHSt); RFX_Double(pFX, _T("[PrsSt]"), m_dPrsSt); RFX_Double(pFX, _T("[O2St]"), m_dO2St); RFX_Double(pFX, _T("[CO2St]"), m_dCO2St); //}}AFX_FIELD_MAP } ///////////////////////////////////////////////////////////////////////////// // CDatabase_01Set diagnostics #ifdef _DEBUG void CDatabase_01Set::AssertValid() const { CRecordset::AssertValid(); }

PAGE 142

132 void CDatabase_01Set::Dump(CDumpContext& dc) const { CRecordset::Dump(dc); } #endif //_DEBUG database_01.h // database_01Set.h : interface of the CDatabase_01Set class // ///////////////////////////////////////////////////////////////////////////// #if !defined(AFX_DATABASE_01SET_H__6988BD3D_0E2E_4BFA_8A6E_BF7594D3C7EC__INCLUDED_) #define AFX_DATABASE_01SET_H__6988BD3D_0E2E_4BFA_8A6E_BF7594D3C7EC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CDatabase_01Set : public CRecordset { public: CDatabase_01Set(CDatabase* pDatabase = NULL); DECLARE_DYNAMIC(CDatabase_01Set) // Field/Param Data //{{AFX_FIELD(CDatabase_01Set, CRecordset) double m_dTemp; double m_dRH; double m_dPrs; double m_dCO2; double m_dO2; double m_dLght; double m_dWght; CTime m_tTime; double m_dRHSt; double m_dPrsSt; double m_dCO2St; double m_dO2St; //}}AFX_FIELD

PAGE 143

133 // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CDatabase_01Set) public: virtual CString GetDefaultConnect(); // Default connection string virtual CString GetDefaultSQL(); // default SQL for Recordset virtual void DoFieldExchange(CFieldExchange* pFX); // RFX support //}}AFX_VIRTUAL // Implementation #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_DATABASE_01SET_H__6988BD3D_0E2E_4BFA_8A6E_BF7594D3C7EC__INCLUDED_) OScopeCtrl.cpp #include "stdafx.h" #include "math.h" #include "OScopeCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__ ; #endif ///////////////////////////////////////////////////////////////////////////// // COScopeCtrl COScopeCtrl::COScopeCtrl() { // since plotting is based on a LineTo for each new point // we need a starting point (i.e. a "previous" point) // use 0.0 as the default first point. // these are public member variables, and can be changed outside // (after construction). Therefore m_perviousPosition could be set to

PAGE 144

134 // a more appropriate value prior to the first call to SetPosition. m_dPreviousPosition1 = 0.0 ; // public variable for the number of decimal places on the y axis m_nYDecimals = 3 ; // set some initial values for the scaling until "SetRange" is called. // these are protected varaibles and must be set with SetRange // in order to ensure that m_dRange is updated accordingly m_dLowerLimit = -10.0 ; m_dUpperLimit = 10.0 ; m_dLowerXLimit = 0.0 ; m_dUpperXLimit = 10.0 ; m_dRange = m_dUpperLimit m_dLowerLimit ; // protected member variable // m_nShiftPixels determines how much the plot shifts (in terms of pixels) // with the addition of a new data point m_nShiftPixels = 4 ; m_nHalfShiftPixels = m_nShiftPixels/2 ; // protected m_nPlotShiftPixels = m_nShiftPixels + m_nHalfShiftPixels ; // protected // background, grid and data colors // these are public variables and can be set directly m_crBackColor = RGB( 0, 0, 255) ; // see also SetBackgroundColor m_crGridColor = RGB( 0, 255, 255) ; // see also SetGridColor // m_crPlotColor = RGB(255, 255, 255) ; // see also SetPlotColor m_crTempColor = RGB(255, 0, 0); m_crPrsColor = RGB(255, 255, 0); m_crRHColor = RGB(255, 0, 255); m_crCO2Color = RGB(255, 255, 255); m_crO2Color = RGB(0, 255, 0); m_crWghtColor = RGB(175, 255, 125); // protected variables // m_penPlot.CreatePen(PS_SOLID, 0, m_crPlotColor) ; m_brushBack.CreateSolidBrush(m_crBackColor) ; // public member variables, can be set directly m_strXUnitsString.Format("Samples") ; // can also be set with SetXUnits m_strYUnitsString.Format("Y units") ; // can also be set with SetYUnits // protected bitmaps to restore the memory DC's m_pbitmapOldGrid = NULL ; m_pbitmapOldPlot = NULL ; } // COScopeCtrl

PAGE 145

135 ///////////////////////////////////////////////////////////////////////////// COScopeCtrl::~COScopeCtrl() { // just to be picky restore the bitmaps for the two memory dc's // (these dc's are being destroyed so there shouldn't be any leaks) if (m_pbitmapOldGrid != NULL) m_dcGrid.SelectObject(m_pbitmapOldGrid) ; if (m_pbitmapOldPlot != NULL) m_dcPlot.SelectObject(m_pbitmapOldPlot) ; } // ~COScopeCtrl BEGIN_MESSAGE_MAP(COScopeCtrl, CWnd) //{{AFX_MSG_MAP(COScopeCtrl) ON_WM_PAINT() ON_WM_SIZE() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // COScopeCtrl message handlers ///////////////////////////////////////////////////////////////////////////// BOOL COScopeCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID) { BOOL result ; static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW) ; result = CWnd::CreateEx(WS_EX_CLIENTEDGE | WS_EX_STATICEDGE, className, NULL, dwStyle, rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top, pParentWnd->GetSafeHwnd(), (HMENU)nID) ; if (result != 0) InvalidateCtrl() ; return result ; } // Create ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::SetRange(double dLower, double dUpper, int nDecimalPlaces) {

PAGE 146

136 ASSERT(dUpper > dLower) ; m_dLowerLimit = dLower ; m_dUpperLimit = dUpper ; m_nYDecimals = nDecimalPlaces ; m_dRange = m_dUpperLimit m_dLowerLimit ; m_dVerticalFactor = (double)(m_nPlotHeight-20) / m_dRange ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetRange ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::SetXUnits(CString string) { m_strXUnitsString = string ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetXUnits ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::SetYUnits(CString string) { m_strYUnitsString = string ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetYUnits ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::SetGridColor(COLORREF color) { m_crGridColor = color ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetGridColor /////////////////////////////////////////////////////////////////////////////

PAGE 147

137 void COScopeCtrl::SetPlotColor(COLORREF color) { m_crPlotColor = color ; m_penPlot.DeleteObject() ; m_penPlot.CreatePen(PS_SOLID, 0, m_crPlotColor) ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetPlotColor ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::SetBackgroundColor(COLORREF color) { m_crBackColor = color ; m_brushBack.DeleteObject() ; m_brushBack.CreateSolidBrush(m_crBackColor) ; // clear out the existing garbage, re-start with a clean plot InvalidateCtrl() ; } // SetBackgroundColor ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::InvalidateCtrl() { // There is a lot of drawing going on here particularly in terms of // drawing the grid. Don't panic, this is all being drawn (only once) // to a bitmap. The result is then BitBlt'd to the control whenever needed. int i ; int nCharacters ; int nTopGridPix, nMidGridPix, nBottomGridPix ; CPen *oldPen ; CPen solidPen(PS_SOLID, 0, m_crGridColor) ; CPen dotPen(PS_DOT,0,m_crGridColor); CFont axisFont, yUnitFont, *oldFont, graphFont; CString strTemp ; // in case we haven't established the memory dc's CClientDC dc(this) ; // if we don't have one yet, set up a memory dc for the grid

PAGE 148

138 if (m_dcGrid.GetSafeHdc() == NULL) { m_dcGrid.CreateCompatibleDC(&dc) ; m_bitmapGrid.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ; m_pbitmapOldGrid = m_dcGrid.SelectObject(&m_bitmapGrid) ; } m_dcGrid.SetBkColor (m_crBackColor) ; // fill the grid background m_dcGrid.FillRect(m_rectClient, &m_brushBack) ; // draw the plot rectangle: // determine how wide the y axis scaling values are nCharacters = abs((int)log10(fabs(m_dUpperLimit))) ; nCharacters = max(nCharacters, abs((int)log10(fabs(m_dLowerLimit)))) ; // add the units digit, decimal point and a minus sign, and an extra space // as well as the number of decimal places to display nCharacters = nCharacters + 4 + m_nYDecimals ; // adjust the plot rectangle dimensions // assume 6 pixels per character (this may need to be adjusted) m_rectPlot.left = m_rectClient.left + 6*(nCharacters) ; m_nPlotWidth = m_rectPlot.Width() ; // draw the plot rectangle oldPen = m_dcGrid.SelectObject (&solidPen) ; m_dcGrid.MoveTo (m_rectPlot.left, m_rectPlot.top+15) ; m_dcGrid.LineTo (m_rectPlot.right, m_rectPlot.top+15) ; m_dcGrid.LineTo (m_rectPlot.right, m_rectPlot.bottom-4) ; m_dcGrid.LineTo (m_rectPlot.left, m_rectPlot.bottom-4) ; m_dcGrid.LineTo (m_rectPlot.left, m_rectPlot.top+15) ; m_dcGrid.SelectObject (oldPen) ; // draw the dotted lines, // use SetPixel instead of a dotted pen this allows for a // finer dotted line and a more "technical" look oldPen = m_dcGrid.SelectObject (&dotPen) ; int nLines = 5; int nDis = (m_rectPlot.bottom-4 m_rectPlot.top-15)/nLines; for(i=1;i
PAGE 149

139 m_dcGrid.SelectObject (oldPen) ; /* nMidGridPix = (m_rectPlot.top + m_rectPlot.bottom)/2 ; nTopGridPix = nMidGridPix m_nPlotHeight/4 ; nBottomGridPix = nMidGridPix + m_nPlotHeight/4 ; for (i=m_rectPlot.left; i
PAGE 150

140 { strTemp.Format ("%.*lf", m_nYDecimals, m_dUpperLimiti*nYUnit) ; m_dcGrid.TextOut (m_rectPlot.left-4, m_rectPlot.top+10+i*nDis, strTemp) ; } // y min m_dcGrid.SetTextAlign (TA_RIGHT|TA_BASELINE) ; strTemp.Format ("%.*lf", m_nYDecimals, m_dLowerLimit) ; m_dcGrid.TextOut (m_rectPlot.left-4, m_rectPlot.bottom, strTemp) ; // x min m_dcGrid.SetTextAlign (TA_LEFT|TA_TOP) ; nDis = (m_rectPlot.right m_rectPlot.left-2)/10; for(i=1;i<11;i++) { strTemp.Format ("%.*lf", m_nYDecimals, m_dLowerXLimit+ i*10) ; m_dcGrid.TextOut (m_rectPlot.left+i*nDis, m_rectPlot.bottom-2, strTemp) ; } /*// m_dcGrid.TextOut (m_rectPlot.left, m_rectPlot.bottom+4, "0") ; // x max m_dcGrid.SetTextAlign (TA_RIGHT|TA_TOP) ; strTemp.Format ("%d", m_nPlotWidth/m_nShiftPixels) ; m_dcGrid.TextOut (m_rectPlot.right, m_rectPlot.bottom+4, strTemp) ; */ // x units m_dcGrid.SetTextAlign (TA_CENTER|TA_TOP) ; m_dcGrid.TextOut ((m_rectPlot.left+m_rectPlot.right)/2-10, m_rectPlot.bottom+10, m_strXUnitsString) ; oldFont = m_dcGrid.SelectObject(&graphFont) ; m_dcGrid.SetTextAlign (TA_CENTER|TA_TOP) ; m_dcGrid.SetTextColor (m_crTextColor) ; //m_dcGrid.TextOut (m_rectPlot.right-20,m_rectPlot.top+50, "Temp") ; m_dcGrid.TextOut (m_rectPlot.right-170,m_rectPlot.top, m_sTitle) ; // restore the font m_dcGrid.SelectObject(oldFont) ; // y units oldFont = m_dcGrid.SelectObject(&yUnitFont) ; m_dcGrid.SetTextAlign (TA_CENTER|TA_BASELINE) ; m_dcGrid.TextOut ((m_rectClient.left+m_rectPlot.left)/2-4, (m_rectPlot.bottom+m_rectPlot.top)/2, m_strYUnitsString) ; m_dcGrid.SelectObject(oldFont) ;

PAGE 151

141 // at this point we are done filling the the grid bitmap, // no more drawing to this bitmap is needed until the setting are changed // if we don't have one yet, set up a memory dc for the plot if (m_dcPlot.GetSafeHdc() == NULL) { m_dcPlot.CreateCompatibleDC(&dc) ; m_bitmapPlot.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ; m_pbitmapOldPlot = m_dcPlot.SelectObject(&m_bitmapPlot) ; } // make sure the plot bitmap is cleared m_dcPlot.SetBkColor (m_crBackColor) ; m_dcPlot.FillRect(m_rectClient, &m_brushBack) ; // finally, force the plot area to redraw InvalidateRect(m_rectClient) ; } // InvalidateCtrl int nTime=0; ///////////////////////////////////////////////////////////////////////////// double COScopeCtrl::AppendPoint(double dNewPoint1) //,double dNewPoint2, double dNewPoint3, // double dNewPoint4,double dNewPoint5) { // append a data point to the plot // return the previous point //double dPrevious1, dPrevious2, dPrevious3, dPrevious4, dPrevious5 ; double dPrevious1; if(nTime<6) { m_dPreviousPosition1 = dNewPoint1 ; m_dCurrentPosition1 = dNewPoint1 ; nTime++; } else { dPrevious1 = m_dCurrentPosition1 ; m_dCurrentPosition1 = dNewPoint1 ; } DrawPoint() ;

PAGE 152

142 Invalidate() ; return dPrevious1 ; } // AppendPoint //////////////////////////////////////////////////////////////////////////// void COScopeCtrl::OnPaint() { CPaintDC dc(this) ; // device context for painting CDC memDC ; CBitmap memBitmap ; CBitmap* oldBitmap ; // bitmap originally found in CMemDC // no real plotting work is performed here, // just putting the existing bitmaps on the client // to avoid flicker, establish a memory dc, draw to it // and then BitBlt it to the client memDC.CreateCompatibleDC(&dc) ; memBitmap.CreateCompatibleBitmap(&dc, m_nClientWidth, m_nClientHeight) ; oldBitmap = (CBitmap *)memDC.SelectObject(&memBitmap) ; if (memDC.GetSafeHdc() != NULL) { // first drop the grid on the memory dc memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, &m_dcGrid, 0, 0, SRCCOPY) ; // now add the plot on top as a "pattern" via SRCPAINT. // works well with dark background and a light plot memDC.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, &m_dcPlot, 0, 0, SRCPAINT) ; //SRCPAINT // finally send the result to the display dc.BitBlt(0, 0, m_nClientWidth, m_nClientHeight, &memDC, 0, 0, SRCCOPY) ; } memDC.SelectObject(oldBitmap) ; } // OnPaint int iTime=0; ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::DrawPoint() { // this does the work of "scrolling" the plot to the left // and appending a new data point all of the plotting is

PAGE 153

143 // directed to the memory based bitmap associated with m_dcPlot // the will subsequently be BitBlt'd to the client in OnPaint int currX, prevX, currY1, prevY1; CPen *oldPen ; CRect rectCleanUp ; if (m_dcPlot.GetSafeHdc() != NULL) { // shift the plot by BitBlt'ing it to itself // note: the m_dcPlot covers the entire client // but we only shift bitmap that is the size // of the plot rectangle // grab the right side of the plot (exluding m_nShiftPixels on the left) // move this grabbed bitmap to the left by m_nShiftPixels // m_dcPlot.ScrollDC(m_nShiftPixels,0,&m_rectPlot,&m_rectPlot,NULL,&rectCleanUp); // establish a rectangle over the right side of plot // which now needs to be cleaned up proir to adding the new point // rectCleanUp = m_rectPlot ; // rectCleanUp.right = rectCleanUp.left + m_nShiftPixels ; // fill the cleanup area with the background // m_dcPlot.FillRect(rectCleanUp, &m_brushBack) ; if(iTime == 0) { m_dPreviousX = m_rectPlot.left; iTime++; } if(m_dPreviousX >= m_rectPlot.right-m_nPlotShiftPixels) { m_dPreviousX = m_rectPlot.left; m_dcPlot.ScrollDC(m_rectPlot.right-m_rectPlot.left,0,&m_rectPlot,&m_rectPlot,NULL,&rectCleanUp); // rectCleanUp = m_rectPlot ; // rectCleanUp.right = rectCleanUp.left + m_nShiftPixels ; // fill the cleanup area with the background m_dcPlot.FillRect(m_rectPlot, &m_brushBack) ; }

PAGE 154

144 m_dCurrentX = m_dPreviousX + m_nPlotShiftPixels; // draw the next line segement //draw the first line // grab the plotting pen //m_crPlotColor = m_crTempColor; m_penPlot.DeleteObject() ; m_penPlot.CreatePen(PS_SOLID, 2, m_crPlotColor) ; oldPen = m_dcPlot.SelectObject(&m_penPlot) ; // move to the previous point // prevX = m_rectPlot.left+m_nPlotShiftPixels; prevX = m_dPreviousX; prevY1 = m_rectPlot.bottom (long)((m_dPreviousPosition1 m_dLowerLimit) * m_dVerticalFactor) ; m_dcPlot.MoveTo (prevX, prevY1-4) ; // draw to the current point // currX = m_rectPlot.left+m_nHalfShiftPixels ; currX = m_dCurrentX; currY1 = m_rectPlot.bottom (long)((m_dCurrentPosition1 m_dLowerLimit) * m_dVerticalFactor) ; m_dcPlot.LineTo (currX, currY1-4) ; // if the data leaks over the upper or lower plot boundaries // fill the upper and lower leakage with the background // this will facilitate clipping on an as needed basis // as opposed to always calling IntersectClipRect if ((prevY1 <= (m_rectPlot.top+15)) || (currY1 <= (m_rectPlot.top+15))) m_dcPlot.FillRect(CRect(prevX, m_rectClient.top, currX+1, m_rectPlot.top+1), &m_brushBack) ; if ((prevY1 >= (m_rectPlot.bottom-4)) || (currY1 >= (m_rectPlot.bottom-4))) m_dcPlot.FillRect(CRect(prevX, m_rectPlot.bottom+1, currX+1, m_rectClient.bottom+1), &m_brushBack) ; // store the current point for connection to the next point m_dPreviousPosition1 = m_dCurrentPosition1 ; // restore the pen m_dcPlot.SelectObject(oldPen) ; m_dPreviousX = m_dCurrentX; } } // end DrawPoint ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::OnSize(UINT nType, int cx, int cy) {

PAGE 155

145 CWnd::OnSize(nType, cx, cy) ; // NOTE: OnSize automatically gets called during the setup of the control GetClientRect(m_rectClient) ; // set some member variables to avoid multiple function calls m_nClientHeight = m_rectClient.Height() ; m_nClientWidth = m_rectClient.Width() ; // the "left" coordinate and "width" will be modified in // InvalidateCtrl to be based on the width of the y axis scaling m_rectPlot.left = 20 ; m_rectPlot.top = 10 ; m_rectPlot.right = m_rectClient.right-10 ; m_rectPlot.bottom = m_rectClient.bottom-25 ; // set some member variables to avoid multiple function calls m_nPlotHeight = m_rectPlot.Height() ; m_nPlotWidth = m_rectPlot.Width() ; // set the scaling factor for now, this can be adjusted // in the SetRange functions m_dVerticalFactor = (double)m_nPlotHeight / m_dRange ; } // OnSize ///////////////////////////////////////////////////////////////////////////// void COScopeCtrl::Reset() { // to clear the existing data (in the form of a bitmap) // simply invalidate the entire control InvalidateCtrl() ; } OScopeCtrl.h // OScopeCtrl.h : header file // #ifndef __OScopeCtrl_H__ #define __OScopeCtrl_H__ #define POINTS 3 ///////////////////////////////////////////////////////////////////////////// // COScopeCtrl window

PAGE 156

146 class COScopeCtrl : public CWnd { // Construction public: COScopeCtrl(); // Attributes public: double AppendPoint(double dNewPoint1); //, double dNewPoint2, double dNewPoint3, // double dNewPoint4, double dNewPoint5); // double AppendPoint(double* dNewPoint); void SetRange(double dLower, double dUpper, int nDecimalPlaces=1); void SetXUnits(CString string); void SetYUnits(CString string); void SetGridColor(COLORREF color); void SetPlotColor(COLORREF color); void SetBackgroundColor(COLORREF color); void InvalidateCtrl(); void DrawPoint(); void Reset(); // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(COScopeCtrl) public: virtual BOOL Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID=NULL); //}}AFX_VIRTUAL // Implementation public: LPCTSTR m_sTitle; int m_nShiftPixels; // amount to shift with each new point int m_nYDecimals; CString m_strXUnitsString; CString m_strYUnitsString; COLORREF m_crTextColor; // temperature color COLORREF m_crBackColor; // background color COLORREF m_crGridColor; // grid color

PAGE 157

147 COLORREF m_crPlotColor; // data color COLORREF m_crTempColor; // temperature color COLORREF m_crPrsColor; // pressure color COLORREF m_crRHColor; // RH color COLORREF m_crCO2Color; // CO2 color COLORREF m_crO2Color; // O2 color COLORREF m_crWghtColor; // O2 color double m_dCurrentPosition1; // current position double m_dPreviousPosition1; // previous position double m_dPreviousX; // previous position double m_dCurrentX; // double m_dCurrentPosition[POINTS]; // current position // double m_dPreviousPosition[POINTS]; // previous position virtual ~COScopeCtrl(); // Generated message map functions protected: //{{AFX_MSG(COScopeCtrl) afx_msg void OnPaint(); afx_msg void OnSize(UINT nType, int cx, int cy); //}}AFX_MSG DECLARE_MESSAGE_MAP() int m_nHalfShiftPixels; int m_nPlotShiftPixels; int m_nClientHeight; int m_nClientWidth; int m_nPlotHeight; int m_nPlotWidth; double m_dLowerLimit; // lower bounds double m_dUpperLimit; // upper bounds double m_dLowerXLimit; // lower bounds double m_dUpperXLimit; // upper bounds double m_dRange; double m_dVerticalFactor; CRect m_rectClient; CRect m_rectPlot; CPen m_penPlot; CBrush m_brushBack; CDC m_dcGrid;

PAGE 158

148 CDC m_dcPlot; CBitmap *m_pbitmapOldGrid; CBitmap *m_pbitmapOldPlot; CBitmap m_bitmapGrid; CBitmap m_bitmapPlot; }; ///////////////////////////////////////////////////////////////////////////// #endif

PAGE 159

LIST OF REFERENCES Arai, Y., Goto, E., Omsa, K., Jul 2003, Growth and Development of Arabidopsis thaliana under hypobaric conditions. Presentation at the 33 rd ICES conference, Vancouver, Canada. strm, K.J., Wittenmark, B., 1997, Computer-controlled System, Theory and Design. Prentice-Hall Inc., Upper Saddle River, NJ. Brown, D., Lacey, R. E., Jul 2002, A Distributed Control System for Low Pressure Plant Growth Chambers. Presentation at the 2002 ASAE Annual International Meeting, Chicago, IL. Bucklin, R.A., Fowler P.A., Rygalov V.Y., Wheelers, R.M., Mu, Y., Hublitz I., Wilkerson, E.G., 2004, Greenhouse Design for the Mars Environment: Development of a Prototype, Deployable Dome. Acta Horticultural, Vol. 659: 127-134. Corey, K. A., Barta, J.D., Wheeler, R. M., 2002, Toward Martian Agricultural: Responses of Plants to Hypobaria. Life Support & Biosphere Science, Vol.8:103-114. Corey, K. A., Bates, M.E., Adams, S. L. 1996, Carbon Dioxide Exchange of Lettuce Plants under Hypobaric Conditions. Advances in Space Research. Vol. 18(4/5): 265-272. Corey, K. A., Barta, D. J., Henninger, D. L., 1997, Photosynthesis and Respiration of a Wheat Stand at Reduced Atmospheric Pressure and Reduced Oxygen. Advances in Space Research, Vol. 20: 1869-1877. Daunicht, H. J., Brinkjans, H. J., 1996, Plant Responses to Reduced Air Pressure: Advanced Techniques and Results. Advances in Space Research, Vol. 18 (4/5): 273-281. Figliola, R.S., Beasley, D.E., 2000, Theory and Design for Mechanical Measurements, 3 rd edition. John Wiley & Sons, Inc., New York, NY. Fowler, P. A., 1998, A Methodology for the Design of Complex Computer Systems in Agriculture and Aquaculture, Ph.D dissertation, University of Florida. Fowler, P. A., Rygalov, V. Y., Bucklin, R. A., Wheeler, R. A., May 2001, Design and Control of Interior Climate of Martian Greenhouses, Presentation at the 2001 ASAE Florida Section Annual Conference, Cocoa Beach, FL. 149

PAGE 160

150 Fowler, P.A., Yeralan, S., Mu, Y., Bucklin, R.A., Rygalov, V., Wheeler, R., Dixon, M., Jul 2002, Monitoring and Control for Artificial Climate Design. Presentation at the 32 rd ICES conference, San Antonio, Texas. Fritschen, L.J., Gay, L.W., 1979, Environmental Instrumentation. Springer-Verlag Inc., New York, NY. Gadre, D.V., 2001, Programming and Customizing the AVR Microcontroller, McGraw-Hill Companies, Inc., New York, NY. Givinish, T.J., Montgomery, R.A., Goldstein, G., 2004, Adaptive Radiation of Photosynthetic Physiology in the Hawaiian Lobeliads: Light regimes, Static light responses, and Whole-plant Compensation Points, American Journal of Botany. Vol. 91:228-246. Goto, E., Iwabuchi, K., Takakura, T., 1995, Effect of Reduced Total Air Pressure on Spinach Growth. Journal of Agricultural Meteorology, Vol. 51(2): 139-143. Goto, E., Ohta, H., Iwabuchi, K., Takakura, T., 1996, Measurement of Net Photosynthetic and Transpiration Rates of Spinach and Maize Plants under Hypobaric Condition. Journal of Agricultural Meteorology, Vol. 52(2): 117-123. Goto, E., Arai, Y., Omasa, K., Jul 2002, Growth and Development of Higher Plants Under Hypobaric Conditions. Presentation at the 32 rd ICES conference. San Antonio, Texas. Hanan, J.J., 1998, Greenhouses: Advanced Technology for Protected Horticulture, CRC Press LLC, Boca Raton, FL. He C., Davies, F.T., Lacey R.E., Ngo, Q., 2004, Hypobaric Conditions Effect Gas Exchange, Gas Exchange, Ethylene Evolution and Growth of Selected Plants for Advanced Life Support (ALS), http://aggie-horticulture.tamu.edu/faculty/davies/research/abstracts/pdfs/He-Davies-Habitation-2004CC.pdf, last accessed: Nov 2004. Iwabuchi, K., Goto, E., Takakura, T., 1996, Germination and Growth of Spinach Under Hypobaric Conditions. Environmental Control in Biology, Vol. 34(3): 169-178. Koning, R.E., 1994, Photosynthesis--The Photo Part. http://koning.ecsu.ctstateu.edu/Plant_Biology/photopart.html, last accessed: Nov.2004. Ohta, H., Goto, E., Takakura, T., Takagi, F., Hirosawa, Y., Takagi, K., 1993, Measurement of Photosynthetic and Transpiration Rates under Low Total Pressures. Presentation at the 1993 ASAE Annual International Meeting, Spokane, Washinton. Schartzkopf, S. H., Mancinelli, R. L., 1991, Germination and Growth of Wheat in Simulated Martian Atmospheres. Acta Astronaut. Vol. 25: 245-247.

PAGE 161

151 Wheeler, R.M., Aug 2000, Can CO 2 be Used as a Pressurizing Gas for Mars Greenhouses? Mars Greenhouses: Concepts and Challenges, NASA Technical Memorandum 2000-208577, Kennedy Space Center, FL. Yeralan, S., Emery, H., 2000, The 8051 Cookbook for Assembly and C with Experiments in Mechatronics and Robotics. Rigel Press, Gainesville, FL.

PAGE 162

BIOGRAPHICAL SKETCH Yang Mu was born in Anhui, China, in 1976. She received her BS in physics in 1997 from the Central University of Nationalities, and MS in electrical engineering in 2000 from Jiangsu University. Her MS thesis topic was “A Distributed Greenhouse Environmental Control System.” In Aug. 2000, she came to the University of Florida to pursue her PhD degree under the supervision of Dr. Ray Bucklin. 152