here is the code if it helps
// Control program for PID control of spray booth thermal and humidity
control using DHT11 , with some modification DHT22 could be used for
higher sensing precision: Paul Verstegen May 2011
#define dht_dpin 6 //no ; here. Set equal to channel sensor is on,
byte bGlobalErr; //for passing error code back from complex functions.
byte dht_dat[4]; //Array to hold the bytes sent from sensor.
int tempF = 0; //holds C to F conversion result
float heatpower = 0; //holds heat power result from PID calculation
float coolpower = 0; //holds chiller power result from PID
calculation
float humidpower = 0; //holds humidifier power result from PID
calculation
float dehumidpower = 0; //holds dehumidifier power result from PID
calculation
float cooldehumidpower = 0; //holds which is greater value cool or
dehumid
int heatPin = 7; //digital pin to run heater SSR
int cooldehumidPin = 8; //digital pin to run chiller/dehumidifier SSR
int humidPin = 9; //digital pin to run humidifier SSR
float heatpercent;
float coolpercent;
float humidpercent;
float dehumidpercent;
#include <PID_v1.h> //include PID library
//Define Variables we'll be connecting to
double SetpointHeat, InputHeat, OutputHeat;
double SetpointCool, InputCool, OutputCool;
double SetpointHumid, InputHumid, OutputHumid;
double SetpointDehumid, InputDehumid, OutputDehumid;
//Specify the links and initial tuning parameters
PID heatPID(&InputHeat, &OutputHeat, &SetpointHeat,4,2,.5, DIRECT);
PID coolPID(&InputCool, &OutputCool, &SetpointCool,4,2,.5, REVERSE);
PID humidPID(&InputHumid, &OutputHumid, &SetpointHumid,4,2,.5,
DIRECT);
PID dehumidPID(&InputDehumid, &OutputDehumid, &SetpointDehumid,4,2,.5,
REVERSE);
float WindowSize = 60000; //this sets time factor of loop in msec
unsigned long WindowStartTime;
unsigned long ComputeStart;
unsigned long ComputeEnd;
unsigned long ComputeTime;
void setup(){
heatPID.SetSampleTime(WindowSize);
coolPID.SetSampleTime(WindowSize);
humidPID.SetSampleTime(WindowSize);
dehumidPID.SetSampleTime(WindowSize);
heatPID.SetOutputLimits(0, WindowSize);
coolPID.SetOutputLimits(0, WindowSize);
humidPID.SetOutputLimits(0, WindowSize);
dehumidPID.SetOutputLimits(0, WindowSize);
//set output pins for SSR control of heater, humidifier, and
dehumidifier/chiller
pinMode(heatPin, OUTPUT);
pinMode(cooldehumidPin,OUTPUT);
pinMode(humidPin,OUTPUT);
SetpointHeat = 25; //sets temperature setpoint in degrees celcius
(make adjustable in final version)
SetpointCool = SetpointHeat + 2; //sets cool to kick in with a 2
degree "dead band" to eliminate oscillation
SetpointHumid = 60; //sets humidity setpoint to 60% humidity (make
adjustable in final version)
SetpointDehumid = SetpointHumid + 2; //sets dehumidifier to kick in
with a 2% "dead band" to eliminate oscillation
//turn the PID on assuming ambient conditions will likely require
steady state in a heating and humidifing condition
heatPID.SetMode(AUTOMATIC);
coolPID.SetMode(MANUAL);
humidPID.SetMode(AUTOMATIC);
dehumidPID.SetMode(MANUAL);
InitDHT();//Does what's necessary to prepare for reading DHT sensor
Serial.begin(9600);
delay(1000);//Let system settle
Serial.println("Humidity and temperature\n\n");
delay(2000); //time to read the message
}//end "setup()"
void loop(){
ComputeStart = millis();
ReadDHT();//This is the "heart" of the program.
//Fills global array dht_dpin[], and bGlobalErr, which
//will hold zero if ReadDHT went okay.
//Must call InitDHT once (in "setup()" is usual) before
//calling ReadDHT.
//Following: Displays what was seen...
switch (bGlobalErr){
case 0:
Serial.print("humidity= ");
Serial.print(dht_dat[0], DEC);
Serial.print(".");
Serial.print(dht_dat[1], DEC);
Serial.print("% ");
Serial.print("temp= ");
tempF = (((1.8)*dht_dat[2])+32); //c to f conversion
Serial.print(tempF, DEC);
//Serial.print(".");
//Serial.print(dht_dat[3], DEC);
Serial.print("F ");
Serial.print(dht_dat[2], DEC);
//Serial.print(".");
//Serial.print(dht_dat[3], DEC);
Serial.print("C ");
if (dht_dat[0] < SetpointDehumid){
humidPID.SetMode(AUTOMATIC);
dehumidPID.SetMode(MANUAL);
OutputDehumid = 0;
InputHumid = dht_dat[0];
humidPID.Compute();
humidpower = OutputHumid;
dehumidpower = OutputDehumid;
}
if (dht_dat[0] >= SetpointDehumid){
humidPID.SetMode(MANUAL);
dehumidPID.SetMode(AUTOMATIC);
OutputHumid = 0;
InputDehumid = dht_dat[0];
dehumidPID.Compute();
dehumidpower = OutputDehumid;
humidpower = OutputHumid;
}
if (dht_dat[2] < SetpointCool){
heatPID.SetMode(AUTOMATIC);
coolPID.SetMode(MANUAL);
OutputCool = 0;
InputHeat = dht_dat[2];
heatPID.Compute();
heatpower = OutputHeat;
coolpower = OutputCool;
}
if (dht_dat[2] >= SetpointCool){
heatPID.SetMode(MANUAL);
coolPID.SetMode(AUTOMATIC);
OutputHeat = 0;
InputCool = dht_dat[2];
coolPID.Compute();
coolpower = OutputCool;
heatpower = OutputHeat;
}
Serial.print("Heat: ");
heatpercent = (heatpower/WindowSize)*100;
Serial.print(heatpercent);
Serial.print("% ");
Serial.print("Cool: ");
coolpercent = (coolpower/WindowSize)*100;
Serial.print(coolpercent);
Serial.print("% ");
Serial.print("Humid: ");
humidpercent = (humidpower/WindowSize)*100;
Serial.print(humidpercent);
Serial.print("% ");
dehumidpercent = (dehumidpower/WindowSize)*100;
Serial.print("Dehumid: ");
Serial.print(dehumidpercent);
Serial.println("% ");
if(coolpower >= dehumidpower){
cooldehumidpower = coolpower;
}
if(dehumidpower >= coolpower){
cooldehumidpower = dehumidpower;
}
ComputeEnd = millis();
ComputeTime = ComputeEnd - ComputeStart;
Serial.print(ComputeTime);
Serial.println(" msec.");
WindowStartTime = millis();
while ((millis()-WindowStartTime) < WindowSize){ //while the
operating window time is less than the window size, the appropriate
pins are turned on or shut off
if (heatpower > (millis()-WindowStartTime)){ //for a
percentage of the window time determined by the PID
digitalWrite(heatPin,HIGH);
}
if (heatpower <= (millis()-WindowStartTime)){
digitalWrite(heatPin,LOW);
}
if (humidpower > (millis()-WindowStartTime)){
digitalWrite(humidPin,HIGH);
}
if (humidpower <= (millis()-WindowStartTime)){
digitalWrite(humidPin,LOW);
}
if (cooldehumidpower > (millis()-WindowStartTime)){
digitalWrite(cooldehumidPin,HIGH);
}
if (cooldehumidpower <= (millis()-WindowStartTime)){
digitalWrite(cooldehumidPin,LOW);
}
}
break;
case 1:
Serial.println("Error 1: DHT start condition 1 not met.");
delay(1000);
break;
case 2:
Serial.println("Error 2: DHT start condition 2 not met.");
delay(1000);
break;
case 3:
Serial.println("Error 3: DHT checksum error.");
delay(1000);
break;
default:
Serial.println("Error: Unrecognized code encountered.");
delay(1000);
break;
}//end "switch"
delay(1000);//Don't try to access too frequently... in theory
//should be once per two seconds, fastest,
//but seems to work after 0.8 second.
}// end loop()
/*Below here: Only "black box" elements which can just be plugged
unchanged into programs. Provide InitDHT() and ReadDHT(), and a
function
one of them uses.*/
void InitDHT(){
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);
}//end InitDHT
void ReadDHT(){
/*Uses global variables dht_dat[0-4], and bGlobalErr to pass
"answer" back. bGlobalErr=0 if read went okay.
Depends on global dht_dpin for where to look for sensor.*/
bGlobalErr=0;
byte dht_in;
byte i;
// Send "start read and report" command to sensor....
// First: pull-down I/O pin for 23000us
digitalWrite(dht_dpin,LOW);
delay(23);
/*
aosong.com datasheet for DHT22 says pin should be low at least
500us. I infer it can be low longer without any]
penalty apart from making "read sensor" process take
longer. */
//Next line: Brings line high again,
// second step in giving "start read..." command
digitalWrite(dht_dpin,HIGH);
delayMicroseconds(30);//DHT22 datasheet says host should
//keep line high 20-40us, then watch for sensor taking line
//low. That low should last 80us. Acknowledges "start read
//and report" command.
//Next: Change Arduino pin to an input, to
//watch for the 80us low explained a moment ago.
pinMode(dht_dpin,INPUT);
delayMicroseconds(40);
dht_in=digitalRead(dht_dpin);
if(dht_in){
bGlobalErr=1;//dht start condition 1 not met
return;
}//end "if..."
delayMicroseconds(80);
dht_in=digitalRead(dht_dpin);
if(!dht_in){
bGlobalErr=2;//dht start condition 2 not met
return;
}//end "if..."
/*After 80us low, the line should be taken high for 80us by the
sensor. The low following that high is the start of the first
bit of the forty to come. The routine "read_dht_dat()"
expects to be called with the system already into this low.*/
delayMicroseconds(80);
//now ready for data reception... pick up the 5 bytes coming from
// the sensor
for (i=0; i<5; i++)
dht_dat[i] = read_dht_dat();
//Next: restore pin to output duties
pinMode(dht_dpin,OUTPUT);
//Next: Make data line high again, as output from Arduino
digitalWrite(dht_dpin,HIGH);
//Next see if data received consistent with checksum received
byte dht_check_sum =
dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
/*Condition in following "if" says "if fifth byte from sensor
not the same as the sum of the first four..."*/
if(dht_dat[4]!= dht_check_sum)
{bGlobalErr=3;}//DHT checksum error
};//end ReadDHT()
byte read_dht_dat(){
//Collect 8 bits from datastream, return them interpreted
//as a byte. I.e. if 0000.0101 is sent, return decimal 5.
//Code expects the system to have recently entered the
//dataline low condition at the start of every data bit's
//transmission BEFORE this function is called.
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
//We enter this during the first start bit (low for 50uS) of the
byte
//Next: wait until pin goes high
while(digitalRead(dht_dpin)==LOW);
//signalling end of start of bit's transmission.
//Dataline will now stay high for 27 or 70 uS, depending on
//whether a 0 or a 1 is being sent, respectively.
delayMicroseconds(30);//AFTER pin is high, wait further period,
to be
//into the part of the timing diagram where a 0 or a 1 denotes
//the datum being send. The "further period" was 30uS in the
software
//that this has been created from. I believe that a higher
number
//(45?) might be more appropriate.
//Next: Wait while pin still high
if (digitalRead(dht_dpin)==HIGH)
result |=(1<<(7-i));// "add" (not just addition) the 1
//to the growing byte
//Next wait until pin goes low again, which signals the START
//of the NEXT bit's transmission.
while (digitalRead(dht_dpin)==HIGH);
}//end of "for.."
return result;
}//end of "read_dht_dat()"