/*Read hum&temp from DHT11 for plant signalling. * Only 3 wires are involved:Vcc, Gnd and a single data line. * Read soil, cap and leaf sensors and assign to variables. * Control a mood led according to variables. * Control 4 relays to take care of the plant. * Dincer Hepguler 2013 * http://borsaci06.com */ int r=0; // red mood int g=0; //green mood int b=255; // blue mood int RelayPin1 = 10; //watering int RelayPin2 = 11; //humidifier int RelayPin3 = 12; //fan int RelayPin4 = 13; const int LeafSensor = A2; // A2 pin is used to read the value of the Leaf Sensor int LeafState; const int CapSensor = A1; // A1 pin used to read capacitive sensor int CapState; const int SoilSensor = A0; // A0 pin used to read val of soil sensor int SoilState; int NumReadings = 20; //number of readings per avarage int StresState; #define dht_dpin 2 // Set equal to channel sensor is on, //where if dht_dpin is 14, sensor is on digital line 14, aka analog 0 //Other digital lines can be used, e.g. D2 byte bGlobalErr;//for passing error code back from complex functions. byte dht_dat[5];//Array to hold the bytes sent from sensor. void setup(){ pinMode(LeafSensor, INPUT); //defines A2 pin as input pinMode(CapSensor, INPUT); //defines A1 pin as input pinMode(RelayPin1, OUTPUT); //defines relay pins as output pinMode(RelayPin2, OUTPUT); pinMode(RelayPin3, OUTPUT); pinMode(RelayPin4, OUTPUT); InitDHT(); //Does what's necessary to prepare for reading DHT Serial.begin(9600); delay(300); //Let system settle Serial.println("Leaf: Soil: Cap: Stres: Hum%: TempC:\n"); delay(700); //Wait rest of 1000ms recommended delay before reading DHT11 } void loop(){ // make a string for assembling the data to log: String dataString = ""; LeafState = ReadLeafAvg(); // reads LeafSensor and stores to LeafState variable //LeafState = map(LeafState, 0,1023,0,255); g = map(LeafState, 0,1023,0,255); dataString += String(LeafState); dataString += "\t"; SoilState = ReadSoilAvg(); SoilState = map(SoilState, 0,1023,0,255); if (SoilState > 50) { digitalWrite(RelayPin1, HIGH); // sets the Relay1 on for watering } else { digitalWrite(RelayPin1, LOW); // sets the relay off } dataString += String(SoilState); dataString += "\t"; CapState = analogRead(CapSensor); // reads CapSensor and stores to CapState variable CapState = map(CapState, 0,1023,0,255); //r = min(CapState, 255); r =255-(CapState+SoilState); dataString += String(CapState); dataString += "\t"; StresState = LeafState + CapState; if (StresState > 100) { digitalWrite(RelayPin1, HIGH); // sets the relay LEDs on digitalWrite(RelayPin2, HIGH); digitalWrite(RelayPin3, HIGH); digitalWrite(RelayPin4, HIGH); delay(1000); // waits for a second digitalWrite(RelayPin1, LOW); // sets the LEDs off digitalWrite(RelayPin2, LOW); digitalWrite(RelayPin3, LOW); digitalWrite(RelayPin4, LOW); delay(1000); // waits for a second } dataString += String(StresState); dataString += "\t"; ReadDHT(); switch (bGlobalErr){ case 0: //Serial.print("Current humidity = "); //Serial.print(dht_dat[0], DEC); //Serial.print("."); //Serial.print(dht_dat[1], DEC); //Serial.print("% "); //Serial.print("temperature = "); //Serial.print(dht_dat[2], DEC); //Serial.print("."); //Serial.print(dht_dat[3], DEC); //Serial.println("C "); dataString += String(dht_dat[0], DEC); dataString += ","; dataString += String(dht_dat[1], DEC); //dataString += "% "; if (dht_dat[0] < 30) { digitalWrite(RelayPin2, HIGH); // sets the Relay2 on for humidifier } else { digitalWrite(RelayPin2, LOW); // sets the relay off } dataString += "\t"; dataString += String(dht_dat[2], DEC); dataString += ","; dataString += String(dht_dat[3], DEC); //dataString += "C "; if (dht_dat[2] > 30) { digitalWrite(RelayPin3, HIGH); // sets the Relay3 on for fan } else { digitalWrite(RelayPin3, LOW); // sets the relay off } break; case 1: Serial.println("Error 1: DHT start condition 1 not met."); break; case 2: Serial.println("Error 2: DHT start condition 2 not met."); break; case 3: Serial.println("Error 3: DHT checksum error."); break; default: Serial.println("Error: Unrecognized code encountered."); break; } //end "switch" //b = SoilState + dht_dat[0]; Serial.println(dataString); delay(1000); //Don't try to access too frequently... rgb(r,g,b); // mood led status. yellowish-green=good, reddish=bad } // end loop() 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);//keep line high 20-40us //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. 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, //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()" int ReadSoilAvg(){ //subroutine for reading soil sensor n times and avarage int i=0; int SoilState=0; for (i=0; i < NumReadings; i++){ SoilState = SoilState + analogRead(SoilSensor); //read sensor n times delay(1); //delay between reads for more stability } SoilState = SoilState / NumReadings; //avarage return SoilState; } int ReadLeafAvg(){ //subroutine for reading leaf sensor n times and avarage LeafState = 0; for (int i=0;i< NumReadings;i++) { LeafState = LeafState + analogRead(LeafSensor); delay(1); } LeafState = LeafState / NumReadings; return LeafState; } // mood led setup. shows state of the plant. void rgb(int r, int g, int b) { analogWrite(9,b); analogWrite(5,r); analogWrite(6,g); }