Automated Greenhouse

 

Technical Project- ELIC 606

 

Section 1: Introduction

 

As a fundamental part of Humber Colleges Electronic Engineering Technologist program students are taught about all aspects of the electronics field. This includes advanced studies in assembly language programming, circuit analysis and design, digital signal processing, control systems, telecommunication principles, and data acquisition. These areas of the electronics field were taught so that students could develop the skills needed to design and troubleshoot problems as they arise.

 

The Technical project course (ELIC 606) at Humber College provides students with the opportunity to showcase what they have learned through the development of a technical project based on one or more of the topics studied.

 

Section 2: Purpose of the Design

As a technical project I choose to design a project that dealt with three of the aspects of the electronics field studied in this program. Those aspects are computer programming, circuit design, and data acquisition.

The technical project I designed was a fully automated data acquisition and control system for a greenhouse using hardware sensors, C++, Labview and a standard PC. The system was designed to monitor both the temperature within the greenhouse and the moisture of soil in the greenhouse. As part of the automation process the temperature transducer will be associated with a heating and cooling system. If the temperature within the greenhouse exceeds a high temperature limit fans will be turned on and remain on until the temperature fall back into an acceptable range. Subsequently, if the temperature falls below a low temperature limit a heating system will be turned on. The system will also have the ability to monitor the moisture of the soil in the greenhouse to determine if water needs to be added. If the soil moisture transducer determines that there is a lack of water in the soil it will have the system turn on water valves.

 

Section 3: Summary

 

The development of such a system was done by creating three sub-systems that were able to uniformly work together. First a hardware system had to be developed to measure temperature and soil moisture information and condition their signals so they were compatible with IBM PC parallel port standards. Second a software program had to be developed to control the hardware, acquire data from the hardware and store the acquired data in a format that labview could read and analysis. The third sub-system was one that interfaces with the software program with labview for data analysis. Each subsystem is described in detail below.

 

Section 3-1: Hardware

 

Section 3-1-1: Objective

 

The purpose of the hardware sub-section is to take two physical pheromones (temperature and soil moisture) and signal condition them so that they generate data signals that can be inputted through a PC’s parallel port. Furthermore the hardware must also use the +5V signals outputted from the PC’s parallel port to operate turn on high voltage devices (heater and fan).

 

Section 3-1-2: Design and troubleshooting

 

Temperature

 

There were several different temperature transducers I investigated to meet the needs of this project. Initially I choose the LM35DZ by National Semiconductors because the specifications for this part states that its operating temperature is 0°c to 100°c and generates 10mV for each degree Celsius above 0°c (0°c = 0mV). This was ideal since the greenhouse measures temperatures in a range of 0°c to 50°c and the analogue to digital converter (ADC) used (ADC0804) uses allows a maximum analogue input of +5V. This meant that the voltage from the transducer only needed to be amplified by a factor of 10 to produce the 0V-5V signals needed by the ADC. Several test were done to verify this temperature to voltage ratio characteristic. The results of these test were not as expected. Despite following the guidelines specified on the product data sheet it was discovered that this the LM35DZ did not have a 10mV/°c. The test was simply to measure the voltage at two different temperatures and find the rate of voltage change with respect to temperature. The test results are shown if table 3-1.

 

Temperature

Expected Voltage

Actual Voltage

15°c

150mV

253mV

25°c

250mV

312mV

Table 3-1

 

The test data shows that the actual rate of voltage change with respect to temperature was 5.9mV/°c with a 164.5mV offset. This test was done with two other LM35DZ transducers to see if the first part was defective. These additional tests provided similar results to the first test. Since the test provided significantly different results from what was expected I choose not to use the LM35DZ. 

 

Next I choose to try a 3KΏ resistive thermistor manufactured by Fenwall. According to data specification sheets for this component it is a non-linear N-type thermistor. The 3K-ohm resistance of this thermistor is better known as its ambient value (resistance at 25°C). The temperature of this thermistor is inversely proportional to its resistance. That is as the temperature increases the resistance decreases and vice versa. Because of time restraints it was not possible to perform all the integrate mathematics necessery to do exact data collection from this thermistor. It was therefore decided to keep the measured range of temperatures small (10°C-40°C) and apply a linear relation that is close to the actual exponential relation and explain in this report the non-linear characteristics of this thermistor. This compromise presented two benefits. Firstly the  temperatures from 10°C to 30°C would remain fairly accurate to their actual values. The second benefit is the use during demonstrations. Although the temperature reported above 30°C is not very accurate (35°C would be interpreted as something close to 40°C), under this condition the thermistor can be heated to 40°C with the body heat of human fingers.

 

The data specifications sheet for this thermistor indicates that the resistance is 5.97KW at 10°C, 3.747KW at 20°C, and 3KW at 25°C. The slope of the 10°C and 30°C resistances was used to signal condition this thermistor. According to the data sheet the resistance at 40°C is 1.598KW but with the applied linear relationship 40°C would be represented by 0.917KW. The Figure 3.1 below better explains this.

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

Figure 3.1: Temperature curves

 

According to the specification sheets for this thermistor its resistance is 5.97K-ohm at 10°c and 0.917K-ohms at 40°C. To signal condition this thermistor test were done to verify the resistive characteristics of this thermistor and the results were as expected.

 

The actual formula that definds the resistance of this N-type thermistor is shown below.

 

Ro(T) = Ro (To)[eY(T-1-To-1)][1]

 

Where:

 

Ro(T)                                      is the resistance at Temperature T

Ro (To)                                     is the resistance at 25°C (3KW)

E                                                                is 2.718

Y                                         is 2923.94 + 4.8657T – 0.005363T2

T                 is the temperature at which R is unknown expressed in degrees Kelvin

                                                             (273.15 + °C)

To                                                                  is 298.15 degrees Kelvin

 

In order to generate a voltage change that was representative of this 10°C to 40°C temperature change I placed the thermistor as one element of a standard wheat stone bridge voltage divider (powered with a 5VDC power supply). The differential voltage produced across Va and Vb of the bridge was used to represent the change in temperature. The other three elements of the wheat stone bridge were 3, 10KΏ potentiometers set to exactly 6KΏ resistors because the resistance at 10°C (minimum temperature) is 5.97KΏ +/- 10%

 

Once the bridge was balanced (4- 6KΏ resistors) the differential voltage across Va and Vb of the bridge was 0V. To determine the differential voltage of this bridge at 50°C the thermistor was replaced with  0.920KΏ of resistors (resistance at 40°C). Once this was done the differential voltage was measured and found to be 1.837V. Therefore the differential voltage range for a temperature range of 10°c – 40°c is 0V – 1.837V.

 

This was verifier mathematically as shown below.

 

Va = 5V x (6KΏ/12KΏ) = 2.5V

Vb = 5V x (0.917KΏ/6.917KΏ) =  0.663V

Therefore, Va – Vb = 1.837V

 

In order for the A/D converter (ADC0804, 8-bit) to produce a full range output the input voltage must be between 0 – 5V. Therefore the 0V - 1.84V output of the wheat stone bridge had to be amplified. To do this a TLC271 single source operational amplified was used with a source voltage of 0-5V was configured as a differential amplifier. The signal was amplified to 3.85V (gain of about 2.2) because that is the max output for the TLC272 single source opamp used when Vdd is 5V. This caused an error in the ADC output since the max moisture level was 3.85V and the ADC was referenced at 0-5V. To resolve this problem I took the output of the ADC and multiplied it by a factor of 1.3 (5V/3.85V = 1.3) with the software to adjust it to a voltage between 0-5V. The down side to doing this is a small lost of resolution (about 20%) but 8-bits was already far more accurate than this system needed to work effectively. This signal conditioning circuit is shown in figure 3-2.

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-2: Temperature circuit

 
Soil Moisture

 

After investigating several different methods of measuring soil moisture content including specially designed soil moisture testers that cost several hundred dollars and pressure sensors I found a simple bi-metallic probe at White Rose that displays the moisture level of soil on a standard galvanometer. After taking this device apart it was discovered that it operates as a simple battery. The potential difference across the two metallic elements is proportional to the soil moisture level. Since no data specification sheets were available for this device I had to measure the potential difference across the two leads at different moisture levels and determine the characteristics of this device. These results are tabulated in table 3-2.

Moisture Level

Voltage (mV)

0

0

2

55

4

112

6

168

8

225

10

280

                        Table 3-2

The test results showed that the moisture level is directly proportional to the potential difference across the two metals by a factor of 28mV per moisture level.

 

Since the moisture pro generates it’s own voltage a differential amplifier was used to amplify the 280mV (level 10) output by a gain of 13.75 to 3.85V. The signal was amplified to 3.85V because that is the max output for the TLC272 single source opamp used when Vdd is 5V.

 

 

 
Gain (Av) = (3.85V/0.28V) = 13.75. This caused an error in the ADC output since the max moisture level was 3.85V and the ADC was referenced at 0-5V. To resolve this problem I took the output of the ADC and multiplied it by a factor of 1.3 with the software to adjust it to a voltage between 0-5V. The down side to doing this is a small lost of resolution but 8-bits was already far more accurate than this system needed to work effectively. The signal conditioning circuit for the soil moisture probe is shown in figure 3-3.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 3-3: Soil Moisture Circuit

 
Analog to Digital conversion for PC parallel port I/O

 

As previously mentioned the parallel port works only with TTL signals (0V and 5V). To obtain relatively high accuracy an 8-bit analog to digital converter was chosen. This provides a resolution of 28 = 256. One problem that arose from the use of an 8-bit ADC was the fact that the status (input) ports of IBM compatible parallel ports only allow 5 bits of data to be inputted at one time. To get around this problem 2-to1 (8 inputs to 4 outputs) multiplexer 74LS157 was connected to the ADC outputs. This allowed the computer to take in the date 4 bits at a time. As you will see later in this report software will be used to reconstruct this data back into its original 8bit byte. Figure 3-4 shows the ADC and multiplexer circuit.

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-4: ADC and Multiplexer

 
Fan and Heater

 

Two 12V, 120mA computer fan were used two show what happens when the temperature goes above or below the acceptable temperature limits. A red fan was used rather then an actual heater because I was unable to find one. The output from the parallel port is 5V 26mA, which is not enough to power the fans. To get around this problem BJT transistor switching circuits were created. Using 2N4124 transistors the feed with 12V, 120mA across the collector-emitter junction and +5V across the base-emitter junction the fan remains off until the base goes low. Once the base (output in of the data port) goes low (0V) the fan turns on. These circuits are shown in figure 3-5 below.

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-5: Fan Switching Circuit

 

Ra = Vcc/Ic-sat = 12V/120mA = 100ohms

Ic-sat = 12V/100ohms = 120mA

Ib-sat = Ic-sat/B = 120mA/100 = 1.2mA

Ib-on = 10X1.2mA = 12mA

Therefore, Rb = 5V/12mA = 417ohms ≈ 470ohms

 

Water Sprayer

 

Because of the high cost of water sprayers I chose to simply use a light emitting diode (LED) to show weather the water pump is on or off.

 

Section 3-2: Software

 

Section 3-2-1: Objective

 

The purpose of the C++ software is to provide an interface between the transducers and the PC. The software program control the hardware, acquire data from the hardware and store the acquired data in a format that labview could read and analysis (tab delimitated spreadsheet format).

 

Section 3-2-1: Design and troubleshooting

 

One key problem arose during the testing of the hardware/ software system. Initially the program was written in C++ with 80x86 assembly code embedded in it. The data I/O functions were written in assembly language. This program worked fine with the hardware. The assembly language code was later removed from the program and replaced with C++ code. The modified program was connected to the hardware but the system would not function correctly. The system would not accept the data in. My first assumption was that one or more of the hardware components had malfunctioned. After several test it was found that all the hardware was functioning correctly. Next I looked at the C++ program for problems. I removed the write line from the first ADC from its connection to the port and manually toggled it high-low to see if data would be transferred. This test showed that data was indeed being transferred through the ADC correctly. This confirmed that the problem was software and not hardware related. After contemplating this revolution the problem became obvious. Assembly language port I/O is done through indirect addressing methods as shown below.

 

MOV   DX, 378H        ; move port address to DX register

MOV   AX, 0fH           ; move data to be outputted to AX register

OUT    DX, AX           ; move contents of AX to port address stored in DX

 

C++ language port I/O is done though direct addressing as shown below.

 

outport(0x378,0x0f);    // 0f is outputted address 378

 

Although it take less time to execute assembly language opcodes then C++ opcodes the three lines shown above still take longer to execute then the one line of C++ code. The write line of the ADC must be sent high and then low if it is to update its output data. The problem was that when the program was first run with the hardware it was with the slower assembly code so the hardware triggering time was ok. The second time the hardware and software were run with the faster C++ code which did not leave enough time between the High low pulse of the ADC write line to allow it to update its outputs. This was verified with a voltmeter. Rather then seeing a 5V to 0V transition the C++ program outputted a constant 2.5V signal. To correct this problem a 100 msec delay was added between the pulses. This corrected the problem.

 

Port address 278h and 378h are known as data ports because they are used for data output from the parallel port. Pins 2 to 9 of the parallel ports 25 pins as output data bits were pin 2 is the LSB and pin 9 is the MSB as shown in the table 3-3 below.

 

Pin #

Pin 9

Pin 8

Pin 7

Pin 6

Pin 5

Pin 4

Pin 3

Pin 2

Bit #

7

6

5

4

3

2

1

0

Table 3-3: Port 378h Bit/ Pin Assignment

 

Port addresses 279h/ 379h uses pins 10,11,12, 13, and 16 as data bit inputs as shown in the table 3-4 below.

 

Pin #

Pin 11

Pin 10

Pin 12

Pin 13

Pin 16

--------

---------

-------

 

Bit #

______

Bit  7

 

Bit 6

 

Bit 5

 

Bit 4

 

Bit 3

 

Bit 2

 

Bit 1

 

Bit 0

Table 3-4: Port 379h Bit / Pin Assignment

 

The PC parallel port is only capable of taking 5 bits in at a time. Therefore to take in the 8-bit number from the ADC I wrote the program to control a multiplexer that split the 8-bit number into 2 4-bit sections (4 LSB’s) and 4 MSB’s. Ports 279h/  379H was used to take in the multiplexer output and ports 27Ah/ 37AH was used to control the multiplexer's select line. Port 279H/ 379H takes in bits 3, 4, 5, 6, and 7 of which I used bits 3, 4, 5, and 6.

 

First I took the 4 LSB’s in and then shifted these 4 bits right 3 times so that they were in the positions of bits 0, 1, 2, and 3 and the upper 4 bits were masked. This manipulated data was then stored in the variable low. Port 37AH was then toggled so that the 4 MSB’s would be outputted from the multiplexer. The program then inputted the 4 MSB’s and shifted the data left once so the data was in the position of bits 4, 5, 6, and 7 and the lower 4 bits (nibble) was masked. This value was stored in a variable called high. Now that the upper and lower bits were in variables they were simply added and the result was stored in a variable called data. Specific information about how the code works can be found in the flow charts[2] (Figure 3-6) and program code shown below.

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-6: Flow Chart of getADCData() Function

 

C++ Program Code

 

/* Name: Automated Greenhouse Project

Started: May 20, 2001

Last Modified: June 15,2001

By: Shawn Bullock

------------------------------------------------------- */

 

/*This part of the program initializes the function libraries to be used

by the program and defines all variable. */

 

#include <fstream.h>            // File I/O functions

#include <conio.h>                // Screen Display Functions

#include <stdio.h>                 // Standard Functions

#include <dos.h>                   // DOS Functions

#pragma inline

 

 

 

/*This part of the program defines all variables used. */

 

int i=0, num = 0, nums = 0;

int condition, low1, low2, high1, high2,hour, minutes;

float t, s, rate, average_temp, total_t = 0;

unsigned char data = 0, data2 = 0;             // Return values from A/D converters

 

int data_port1 = 0x378;                    // Output port of parallel port 1 (LPT1)

int status_port1 = 0x379;                  // Input port of parallel port 1 (LPT1)

int control_port1 = 0x37a;                // Input/Output port of parallel port 1 (LPT1)

int data_port2 = 0x278;                    // Output port of parallel port 2 (LPT2)

int status_port2 = 0x279;                  // Input port of parallel port 2 (LPT2)

int control_port2 = 0x27a;                // Input/Output port of parallel port 2 (LPT2)

 

/* This function displays a program title to the screen */

 

void msg1(void)  {

   clrscr();                                // Clear Screen

   gotoxy (1,2);           // Goto cursor location 1,2

   printf("\t*****************************************************************\n\t");

   printf("\t        Welcome to the Automated Greenhouse Program    \n\t");

   printf("                     By: Shawn Bullock                                          \n");

   printf("\t*****************************************************************\n\n");

   }

  

   void msg1a(void)  {

   printf("\t This system monitors both the temperature and soil moisture level\n");

   printf("\t within the greenhouse and operates a water sprayer, fan, and \n");

   printf("\t heater as needed. The temperature is measured in a range of \n");

   printf("\t10 - 50 degrees celcius. If the temperature goes below 15 degrees \n");

   printf("\t C a heater is turned on and if it goes above 35 degrees C a fan is \n");

   printf("\t turned on. Soil moisture level is measured on a scale of 0-10 were \n");

   printf("\t0 is dry and 10 is wet. If the level goes below 3 a water sprayer is \n");

   printf("\t turned on. \n”);

                                      }

 

/* This function add one line to the message of function msg1*/

 

void msg2(void)  {

   gotoxy (15,25);                   // Goto cursor location 15,25

   printf("\t\t *********press any key to continue********                     ");

   getch();                                // Waits for any key to be pressed

                 }

 

 

 

/* This function add one line to the message of function msg1*/

 

void msg3(void)  {

   gotoxy (15,25);                   // Goto cursor location 15,25

   printf("\t**************press any key to stop program***********");

                 }

 

/* This function obtains the sampling rate from the user*/

 

void setup_screen(void) {

   clrscr();

   gotoxy(5,2);

   printf("\t------------------------------------------------------------------                     \n");

   printf("\t               AUTOMATED GREENHOUSE SETTINGS         \n");

   printf("\t------------------------------------------------------------------                     \n\n");

   printf("\n\t Please enter the system sample rate in minutes \n\t ");

   scanf("%f",&rate);

   gotoxy (1,15);

   printf("\t      *********press any key to start system********               ");

   }

 

/* The following two function controls the A/D converters and Multiplexers.

It toggles the A/D write line and multiplexer select line. It also inputs 8-bit

sample temperature 4 bits at a time and reassembles it. These function returns the temperature value in a variable called data and the soil moisture values in a

variable called data2. The control port (0x279 and 0x379)inputs four bits of data

in bit locations 4, 5, 6, and 7 so once the data in stored in memory it must be

shifted into the proper bit locations for its application*/

 

/*Temperature data collection through parallel port 1*/

 

unsigned char getADCData(void)          {

  outport(data_port1,0x00);   // Bit 0 of the data port outputs low signal to

                                               // ADC write line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  outport(data_port1,0x01);  // Bit 0 of the data port outputs high signal to

                                                 // ADC write line

  delay(100);                        // 100 msec. delay to compensate for hardware delay

  outport(control_port1,0x00); // Bit 2 of control port outputs low signal to

                                                    // multiplexer chip select line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  low1 =inport(status_port1);            // Inputs lower 4 bits of ADC output

  low1=(low1 >>3);                             // Shift bits into correct bit locations

  low1=(low1 & 0x0f);            // Mask the upper 4 bits.

  outport(control_port1,0x04);          // Bit 2 of control port outputs high signal to

                                                            // multiplexer chip select line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  high1=inport(status_port1);            // Inputs upper 4 bits of ADC output

  high1=(high1 <<1);              // Shift data into correct bit locations

  high1=(high1 & 0xf0);        // Mask the lower 4 bits.

  data=(high1 + low1);           // Reconstruct the 8-bit ADC output by adding

                                                          // the two shifted and masked numbers inputted

  return data;                                       // Return value of this function

                                                                                                                                            }

 

/*Soil moisture data collection through parallel port 2*/

 

  unsigned char getADCData2(void)          {

  outport(data_port2,0x00);              // Bit 0 of the data port outputs low signal to

                                                            // ADC write line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  outport(data_port2,0x01);              // Bit 0 of the data port outputs high signal to

                                                            // ADC write line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  outport(control_port2,0x00);          // Bit 2 of control port outputs low signal to

                                                            // multiplexer chip select line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  low2 =inport(status_port2);            // Inputs lower 4 bits of ADC output

  low2=(low2 >>3);                             // Shift bits into correct bit locations

  low2=(low2 & 0x0f);            // Mask the upper 4 bits.

  outport(control_port2,0x04);          // Bit 2 of control port outputs high signal to

                                                            // multiplexer chip select line

  delay(100);                           // 100 msec. delay to compensate for hardware delay

  high2=inport(status_port2);            // Inputs upper 4 bits of ADC output

  high2=(high2 <<1);              // Shift data into correct bit locations

  high2=(high2 & 0xf0);         // Mask the lower 4 bits.

  data2=(high2 + low2);         // Reconstruct the 8-bit ADC output by adding

                                                // the two shifted and masked numbers inputted

  return data2;                                    // Return value of this function

            }

 

/* This function displays the collected data on the screen, saves it to a binary

file and allows the user to stop the program.*/

 

void write_2_file(void)     {

  ofstream ofs("c:\\temp.dat", ios::binary);              // Creates Binary file

  if (ofs == NULL)                   // Displays message if file can not be created

             {

      gotoxy(10,6);

      cerr << "Problem!!! File could not be opened (or created) \n";

              }

  while (!kbhit())         {            // Executes loop until any key is pressed

      if (i > 0 )    {                       // Finds the average of current and all temperatures

      total_t = total_t + ((data/6.375)+10);     //measured

      average_temp = total_t/(i);

      }

      else

      {

      average_temp = total_t;

      }

      i++    ;                                // Increment loop count

      minutes = i*rate;              // Determines the time of sampling

 

      unsigned char tmp = getADCData(); // Moves return value from getADCData

                                                                        // to variable tmp

      unsigned char soil = getADCData2();// Moves retutn value from getADCData2

                                                                        // to variable soil

      t = ((tmp/6.375)+10)*1.3;                        // Converts the temperature data from

                                                                        // a 0-255 step size to a value between

                                                                        // 10 and 50

      s =  (soil/25.5)*1.3;                                              // Converts the soil data from

                                                                        // a 0-255 step size to a value between

                                                                        // 0 and 10

/* The 1.3 multiple is to adjust the ADC output. Since the amplifiers output is 3.85V max and the ADC reference voltage is 0-5V, 3.85V in is actually equal to 0xffH, which the ADC outputs when 5V is inputted. The 1.3 simply adjust the ADC output to the actual temp. and moisture level. */

      gotoxy(5,10);

      printf("Temperature: ");               // Displays temperature data on the

      printf("%3.2f degrees celcius\t",t);         // screen

      printf(" Soil Moisture Level: ");               // Displays soil moisture data on the

      printf("%3.2f \n",s);                                  // screen

      printf("\t Currently taking sample number %d \t\n",i); // Displays sample #

                                                                                                  // on screen

      printf("Time elasped since first sample: %d minutes\t\n",minutes);

      printf("The average temperature is: %3.2f Degrees Celcius\n",average_temp );

 

      if (t>35)                 // If temperature is > then 35 degrees C fan turns on

                        {

      gotoxy(5,15);

      printf ("Fans Turned On \n");

      outport (data_port1, 0x00);                    // Outputs low signal to BJT's base

            }

      else

      {

      gotoxy(5,15);

      printf ("                            \n");

      outport (data_port1, 0x01);                    // Outputs high signal to BJT's base

          }

      if (t<15)                 // If temperature is < then 15 degrees C heater turns on

         {

      gotoxy(5,15);

      printf ("Heater Turned On  \n");

      outport (data_port1, 0x00);                    // Outputs low signal to BJT's base

            }

      else

         {

      gotoxy(5,15);

      printf ("                            \n");

      outport (data_port1, 0x10);                    // Outputs high signal to BJT's base

         }

 

      if (s<3)                  // If soil moisture is below level 3 watering system turns on

         {

      gotoxy(5,16);

      printf ("Watering System Turned On  \n");

      outport (data_port2, 0x01);                    // Outputs high signal

            }

      else

         {

      gotoxy(5,16);

      printf ("                            \n");

      outport (data_port2, 0x00);                    // Outputs low signal

         }

 

      ofs << (int)i << "\t";                                  // Writes sample number to file and tab

      ofs << (float)average_temp << "\t";       // Writes average temperature to file

      ofs << (float)t << "\t";                               // Writes temperature to file and tab

      ofs << (float)s << "\n";                             // Writes soil to file and carrage return

   if (rate == 0)            {                       // Creates delay between samples.

                        sleep(rate);   }

   else {

                        sleep(rate -0.8);         }

                                                            }

   ofs.close();                                                     // Closes file once loop stops.

   }

 

/* Main program starts here */

 

   void main(void)

    {

   msg1();                                                         // Display Title message

   msg1a();                                                      // Displays program discription

   msg2();

   setup_screen();                                          // Runs sample rate collection function

   clrscr();                                                        // Clears the screen

   msg1();                                                        // Display Title message

   msg3();

   write_2_file();                                              // Runs the write_3_file function

   clrscr();                                                        // Clears the screen

   ends;                                                            // exits program

   }  ;

 

Section 3-3: Labview Software

 

Section 3-3-1: Objective

 

The purpose of the labview software is to provide a graphic user interface that could be used to run the entire system. Furthermore the labview software is to be used to display the data collected on bar graphs.

 

Section 3-3-2: Design and troubleshooting

 

The virtual instrument (VI) created to meet this objective consists of several sub-VI’s (sub-programs). To explain how the program works each sub-VI will be explained individually.

 

 
Figure 3-6 shows the front panel for the system. The VI works as follows. First the user must log in to the system. The user cannot do anything until the login procedure has been preformed successfully. A red LED lights up once access to the system has been granted. Next the user presses the start program button to run the C++ program. When the C++ program has been closed the user can use the temperature and soil moisture data buttons to view the data collect on a graph. The system also has a button to stop the VI and close labview completely.

 

 

 

 

 

 

                                    

 

 

 

 

 

 

 

 

 

 

 

 

  Figure 3-7: System Front Panel          

 

 
 

 

 

 

 

 

 

 

 

 

 


                                                                                                                                                           

 

   

                                                            Figure 3-8: VI Hierarchy

 

Figure 3-8 shows a tree chart of all the sub-VI’s used in this program.

 

No Event State (-1)

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


                                                    Figure 3-9: No Event State

 

This VI searches the menu cluster for a button press (true output). If the button pressed is 0 (login) or 4 (stop) the select function is true and the operation can be preformed. If any other button is pressed it returns to the no event state (-1) of the case structure.

 

Login state (0)

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-10: Verify VI

 

The while loop structures the VI to continue checking for a match until a name match occurs or there are no more rows in the table. The case structure checks if name input matches one listed in the first column of the table. The loop continues until a name match is found. The index array function is used to pull the names array out of the table. The array size function returns the size of the names array. The decrement function decreases the number of names in the array by one so that it can control the while loop which starts indexing at zero. The equal function is used to check if the name input matches a table entry and if the password also matches the table entry. The less then function controls the while loop conditional. The loop continues to run while the current iteration number is less than the number of rows in the table. The NOR function also controls the while loops conditional so that the loop continues until a match is found or there are no more rows in the table. The empty string function is also used. If the names match but not the passwords or if neither match, then an empty string is returned to name confirmed indicator. Finally the select function is used along with the password matching. If the password matches the current name is sent to the name confirmed indicator. Otherwise, the empty string is sent.

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Figure 3-11: Login VI

 

The Login Name local variable is used to reset the login name to an empty string at start-up. The Password local variable resets the password string to an empty string. The empty string constant passes string values to the login name and password local variables. The login name attribute node changes the property to key focus and wires a true constant to it.

 

Start Program State (1)

 
 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 


                                                Figure 3-11: Start Program VI.

 

                                                                        Figure 3-12: Start Program VI

 

This VI uses the system execute function to run the windows program attached to it. The file name to be executed is simply attached to the file input as a constant variable.

 

Temperature Data State (2)

 
 

 

 

 

 

 

 

 

 

 

 

 

 


Text Box:

 

 

 

           

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 


           

3-13: Temperature Data VI

 

The Read Spreadsheet function is used to read the data from the disk file created. Two Index Array functions were used to read the values from each column of the file and rewriting it into two rows of a 2 dimensional array. Column 0 contained the sample number and column 2contained the temperature at the time of sampling. For display purposes I wanted the data to be displayed in columns on a spreadsheet table, as it appears in the disk file so a Transpose 2D Array function was used to transpose the two rows of the array back into to columns. Now that the array contained all the information of the disk file I outputted the array’s contents to a Spreadsheet Table function. The T Fractional function was added to the VI to define the digits of precision displayed to two significant digits. This VI also sends the temperature values sampled to a waveform graph that displays temperature versus sample number.

 

Soil Moisture State (3)

 

 
 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

 

 

 

 

 

 


                                                                                                              3-14: Soil Moisture VI

 

This VI is essential the same as the temperature data VI. The only difference is the columns indexed from the disk file.

 

Stop State (4)

 
 

 

 

 

 

 

 

 

 

 


                                                                                                                                                   

                                                      Figure 3-15: Stop State

 

When the stop button is presses a false state is sent to the while loop conditional so the application stops running. The quit labview function is used to cause the application to completely close labview and return to the operating system.

 

4-1      Conclusion and Recommendations

 

Through in-depth research, and a lot of trial and error troubleshooting the automated greenhouse was created.  The hardware and software created for this project worked well each other. While several problems were encountered during the development of this project they were dealt with logically and eventually resolved.

 

There are many recommendations that I plan to follow up on and implement in the future.

 

With regards to the hardware, I built an ISA expansion card with an Intel 8255 PPI chip to provide three 8-bit input/ output ports between the PC and the outside world. Unfortunately there was a fault in the board built (probably a short somewhere) that prevented it from working correctly. When the board is plugged into the ISA expansion slot the computer will boot p into windows but no video output is present. I investigated the possibility that there might be a resource conflict between the PPI card (0x280-0x283) and the video card but found no such conflict. I also tried it in a different computer but found the same problem. Do to time restraints I was unable to troubleshoot this problem for use with this project. I plan to trouble shoot this board and rewrite the C++ program to interface with the 8255 PPI rather then the parallel port since it will remove the need for too parallel ports and the 8-bit output of the ADC can be inputted directly into the PC without the need for a multiplexer.

 

With regards to software, I would like to investigate the possibility of making this system accessible from remote locations through the Internet. This is a topic I have done some investigation on and would like to study further. There is a small interface board created by Dallas Semiconductors called TINI that uses an Intel 8051 microprocessor to such remote hardware control. I want to look into the possibility of purchasing one of these boards and eventually control the green house with it.

 

With this project most of the emphasis was placed on software design (C++ and Labview) with less emphasis on hardware design partially do to time restriction. I plan to investigate method that would allow me to control X10 compliant 120VAC fans, heaters and water sprinkler systems. This should be possible with the use of relays and/ or opto-isolator devices.

 

The labview program was a lot more challenging than first expected. The programs help files were my greatest source of information. Through a lot of trial and error I was however able to build it to do what it was originally intended to do. Provide a GUI that links the C++ program to it and displays the information collected by the C++ program on bar graphs. Special thanks are given to former Humber College teacher and National Instruments Engineer Ted White for his help with the C++ to labview interfacing portion of the program.

 

The last recommendation that I have is not related to the project characteristics. My last recommendations is to not try doing a project like this alone again. While it was a rewarding experience to design this system by myself, it would have been a lot less stressful to have worked with a team.

 

Acknowledgements

 

The follow books and web sites were used as references in the production of this report: -

 

-         Introductory Electronic Devices and Circuits, 4th Edition By Robert T. Paynter

 

-         Electronic Devices & Circuit Theory, 5th Edition By Robert Boylestad and Louis Nashelsky

 

-         Motorola on-line, Manufacture of Solid State Devices (http://www.motorola.com)

 

-         Fairchild Semiconductors on-line, Manufacturer of Solid State Devices (http://www.fairchildsemi.com)

 

-         Texas Instruments on-line, Manufacturer of Solid State Devices (http://www.ti.com)

 

-   The 80x86 IBM PC and compatible Computers

    (Volumes I & II) by Muhammad Ali Mazidi and

    Janice Gillispie Mazidi

 

-         Former Humber College teacher and current Nation Instruments Engineer Ted White.

 

 

Appendix A:  Data Specification Sheets

 

LM35 Thermocoupler

 

ADC0804 A/D Converter

 

TLC272 Opamp

 

FENWELL 3K THERMISTOR

 

74LS157 Multiplexer



[1] Information provided by www.rtie.rti-corp.com/ntccappln.htm

[2] Note port 378H, 379H, and37AH are respectively the same as ports 278H, 279H, and 27AH.