Components and supplies
resistor 2k ohm
5V 2.5A Switching Power Supply
grounded power cable
Resistor 10k ohm
yellow wire nuts
Alphanumeric LCD, 16 x 2
Arduino Nano R3
Decora 2-Gang Midway Nylon Wall Plate - White
decora duplex outlet, white
Jumper wires (generic)
2-Gang 47 cu. in. PVC New/Old Work Electrical Box (B249B)
Grove - 2-Channel SPDT Relay
DHT11 Temperature & Humidity Sensor (3 pins)
Tools and machines
Soldering iron (generic)
Project description
Code
Humidity controller code
c_cpp
code for operating the humidity controller
1//HUMIDITY CONTROLLER 1.1 2//written for NANO 3 4//controls and displays relative humidity 5//sesnor used is DHT11 6//uses active-low relay module to control live lines for 2 standard electrical outlets 7//uses i2c lcd to display humidity and humidity setting 8//turns display off during inactivity 9//setting is adjustable from 10%-90% using 2 buttons 10//backlight of LCD is controlled by pin 4, connected to top LED jumper pin on i2c backpack 11//serial communications to monitor to ensure all code is working. 12 13//added: "system off" function - allows both outlets to be turned off 14 15// █ G █ L █ O █ B █ A █ L █ S █ 16#include <Wire.h> 17#include <LiquidCrystal_I2C.h> 18#include <dht.h> 19 20// set the LCD address to 0x27 for a 16 chars and 2 line display 21LiquidCrystal_I2C lcd(0x27, 16, 2); 22 23dht DHT; 24 25#define DHT11_PIN A2 26 27//buttons and variables to adjust calibration 28int calupbtn = A0; 29int calup; 30int caldownbtn = A1; 31int caldown; 32 33//i2c PINS A4, A5 34 35//pin for turning on humidifier relay 36int humidifier = 3; 37//pin for turning on the fan relay 38int fan = 2; 39//pin for turning on LCD backlights 40int lcdlight = 4; 41 42//calibration variable 43int setpoint = 50; //feedback setpoint. 44bool calstate = false; //enables calibration adjustments only when LCD is ON. 45 46//backlight timing variables 47int displtime = 12000; //amount of time the display is to be on before turning off 48unsigned long displtimeon; //last recorded time display timer was reset 49int calunlock = 0; //loop counter for unlocking calibration 50 51//sensor timing variables 52unsigned long lastcheck; //last time DHT was read 53long interval = 30000; //time between DHT readings 54 55//system variables 56bool syson = true; //reference for system on/off. 57byte systog = 2; //even number toggles on, odds toggle off 58int syslock = 0; //loop counter for unlocking system toggle 59 60// █ S █ E █ T █ U █ P █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ 61void setup(){ 62 63 Serial.begin(9600); //serial communication used to ensure code is working correctly. 64 65 lcd.init(); //initialize LCD 66 lcd.backlight(); //enable LCD backlight, but doesn't turn it on 67 68 lastcheck = 0; 69 digitalWrite(lcdlight, HIGH); 70 Serial.println("STARTING"); 71 lcd.print(" STARTING"); 72 73 //pin assignments 74 pinMode(calupbtn, INPUT); 75 pinMode(caldownbtn, INPUT); 76 pinMode(humidifier, OUTPUT); 77 pinMode(fan, OUTPUT); 78 pinMode(lcdlight, OUTPUT); 79 delay(1000); 80 81 82 //test fan 83 lcd.setCursor(0,1); 84 lcd.print("<FAN> HMDFR "); 85 digitalWrite(fan, LOW); 86 digitalWrite(humidifier, HIGH); 87 delay(6000); 88 //test humidifier 89 lcd.setCursor(0,1); 90 lcd.print(" FAN <HMDFR> "); 91 digitalWrite(fan, HIGH); 92 digitalWrite(humidifier, LOW); 93 delay(6000); 94 //stop startup test 95 digitalWrite(humidifier, HIGH); 96 digitalWrite(fan, HIGH); 97 lcd.clear(); 98 99 displtimeon = millis(); 100 101 int chk = DHT.read11(DHT11_PIN); 102 lastcheck = millis(); 103 104 lcd.setCursor(0,0); 105 lcd.print("Humidity: "); 106 lcd.setCursor(13,0); 107 lcd.print(DHT.humidity); 108 lcd.setCursor(15,0); 109 lcd.print("% "); 110 lcd.setCursor(0,1); 111 lcd.print("setting: "); 112 lcd.setCursor(13,1); 113 lcd.print(setpoint); 114 lcd.setCursor(15,1); 115 lcd.print("% "); 116 delay(100); 117} 118 119// █ L █ O █ O █ P █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ 120void loop(){ 121 122 //check calibration buttons 123 calup = digitalRead(calupbtn); 124 caldown = digitalRead(caldownbtn); 125 126 if(calup == HIGH and caldown == HIGH){ //--------SYSTEM TOGGLE 127 syslock ++; 128 Serial.println(syslock); 129 if(syslock == 20){ //if both buttons held down for this many loops 130 systog++; 131 if(systog % 2 == 1){ //--------SYSTEM OFF 132 syson = false; 133 digitalWrite(fan, HIGH); 134 digitalWrite(humidifier, HIGH); 135 digitalWrite(lcdlight, HIGH); 136 Serial.println("SYSTEM TURNED OFF"); 137 lcd.clear(); 138 lcd.print(" SYSTEM OFF"); 139 lcd.setCursor(0,1); 140 lcd.print(" hold both btns"); 141 delay(2000); 142 lcd.setCursor(0,1); 143 lcd.print(" to turn on "); 144 displtimeon = millis(); 145 } 146 if(systog % 2 == 0){ //--------SYSTEM ON 147 syson = true; 148 Serial.println("SYSTEM TURNED ON"); 149 digitalWrite(lcdlight, HIGH); 150 lcd.clear(); 151 lcd.print(" SYSTEM ON"); 152 delay(2000); 153 lcd.clear(); 154 displtimeon = millis(); 155 } 156 syslock = 0; 157 } 158 } 159 else(syslock = 0); 160 161 //read humidity at appropriate intervals 162 if(millis() > lastcheck + interval and syson == true){ //read the DHT humidity 163 int chk = DHT.read11(DHT11_PIN); 164 lastcheck = millis(); 165 Serial.print("DHT read = "); 166 Serial.print(DHT.humidity); 167 Serial.print("%"); 168 Serial.println(" "); 169 } 170 171 //turn on the led lights when calibration buttons are pressed 172 if(calup == HIGH xor caldown == HIGH){ 173 digitalWrite(lcdlight, HIGH); 174 calstate = true; 175 displtimeon = millis(); //set display timer 176 Serial.println("cal btn ACTIVE"); 177 if(syson == false){ 178 digitalWrite(lcdlight, HIGH); 179 lcd.clear(); 180 lcd.print(" SYSTEM OFF"); 181 lcd.setCursor(0,1); 182 lcd.print(" hold both btns"); 183 delay(3000); 184 lcd.setCursor(0,1); 185 lcd.print(" to turn on "); 186 displtimeon = millis(); 187 } 188 } 189 190 if(calstate == true and syson == true){ //--------DISPLAY ROUTINE 191 Serial.println("printing display"); 192 //display variables on LCD 193 lcd.setCursor(0,0); 194 lcd.print("Humidity: "); 195 lcd.setCursor(13,0); 196 lcd.print(DHT.humidity); 197 lcd.setCursor(15,0); 198 lcd.print("% "); 199 lcd.setCursor(0,1); 200 lcd.print("setting: "); 201 lcd.setCursor(13,1); 202 lcd.print(setpoint); 203 lcd.setCursor(15,1); 204 lcd.print("% "); 205 delay(100); 206 207 calunlock ++; 208 //keeps calibration locked until display cycles 5 times after initially turned on 209 //prevents adjustments on initial button press. 210 } 211 212//--------CALIBRATION ADJUSTMENTS 213 if(calup == HIGH and caldown == LOW and calstate == true and syson == true){ 214 if(setpoint < 90 and calunlock > 5){ 215 setpoint = setpoint + 5; //increase setpoint 216 Serial.println("adj setpoint up"); 217 } 218 Serial.println(setpoint); 219 delay(100); 220 displtimeon = millis(); //reset backlight timeout 221 } 222 223 if(caldown == HIGH and calup == LOW and calstate == true and syson == true){ 224 if(setpoint > 10 and calunlock > 5){ 225 setpoint = setpoint - 5; //decrease setpoint 226 Serial.println("adj setpoint dn"); 227 } 228 Serial.println(setpoint); 229 delay(100); 230 displtimeon = millis(); //reset backlight timeout 231 } 232 233 if(millis() > displtimeon + displtime){ //-----------------BACKLIGHT TIMEOUT 234 digitalWrite(lcdlight, LOW); //turn off the screen 235 calstate = false; 236 Serial.println("displ + backlights off"); 237 lcd.clear(); 238 calunlock = 0; //lock calibration 239 } 240 241 if(millis() < lastcheck){ 242 lastcheck = millis(); //reset timers in a millisecond rollover 243 } 244 245 //--------SETPOINT ERROR PROCEDURE 246 if(setpoint > 91 or setpoint < 9){ //in case setpoint is ever out of bounds 247 Serial.println("O/B ERROR"); 248 digitalWrite(lcdlight, HIGH); 249 lcd.clear(); 250 lcd.print("O/B ERROR"); //display error message on lcd 251 lcd.setCursor(0,1); 252 lcd.print("RESETTING"); 253 delay(1000); 254 for(int count = 9; count >= 0; count = count - 1){ 255 lcd.setCursor(15,1); 256 lcd.print(count); //count down from 10 257 delay(1000); 258 } 259 setpoint = 50; //reset setpoint at 50. 260 displtimeon = millis(); 261 } 262 263 //turn on humidifier relay if below setpoint --------RELAY CONTROL 264 //RELAY MODULE IS ACTIVE LOW 265 if(DHT.humidity <= setpoint - 3 and syson == true){ //if humidity is 3% lower than setpoint 266 Serial.println("humidifier ON, fan OFF"); 267 digitalWrite(humidifier, LOW); //turn on humidifier 268 digitalWrite(fan, HIGH); 269 } 270 else if(DHT.humidity >= setpoint + 3 and syson == true){ //if humidity is 3% above setpoint 271 Serial.println("humidifier OFF, fan ON"); 272 digitalWrite(humidifier, HIGH); //turn on fan 273 digitalWrite(fan, LOW); 274 } 275 else{ 276 Serial.println("all off"); //if humidity is within 3% of setpoint 277 digitalWrite(humidifier, HIGH); //turn both off 278 digitalWrite(fan, HIGH); 279 } 280 //delay(700); //un-comment for serial debugging 281 282 Serial.print("setpoint = "); 283 Serial.println(setpoint); 284 285 //delay(700); //un-comment for serial debugging 286} 287 288/* WIRING DIAGRAMS 289 https://66.media.tumblr.com/98426b566744beacdd42bc0221092b76/tumblr_pvr0u8kvZy1yrmjh9o1_1280.png 290 */
Humidity controller code
c_cpp
code for operating the humidity controller
1//HUMIDITY CONTROLLER 1.1 2//written for NANO 3 4//controls and displays relative humidity 5//sesnor used is DHT11 6//uses active-low relay module to control live lines for 2 standard electrical outlets 7//uses i2c lcd to display humidity and humidity setting 8//turns display off during inactivity 9//setting is adjustable from 10%-90% using 2 buttons 10//backlight of LCD is controlled by pin 4, connected to top LED jumper pin on i2c backpack 11//serial communications to monitor to ensure all code is working. 12 13//added: "system off" function - allows both outlets to be turned off 14 15// █ G █ L █ O █ B █ A █ L █ S █ 16#include <Wire.h> 17#include <LiquidCrystal_I2C.h> 18#include <dht.h> 19 20// set the LCD address to 0x27 for a 16 chars and 2 line display 21LiquidCrystal_I2C lcd(0x27, 16, 2); 22 23dht DHT; 24 25#define DHT11_PIN A2 26 27//buttons and variables to adjust calibration 28int calupbtn = A0; 29int calup; 30int caldownbtn = A1; 31int caldown; 32 33//i2c PINS A4, A5 34 35//pin for turning on humidifier relay 36int humidifier = 3; 37//pin for turning on the fan relay 38int fan = 2; 39//pin for turning on LCD backlights 40int lcdlight = 4; 41 42//calibration variable 43int setpoint = 50; //feedback setpoint. 44bool calstate = false; //enables calibration adjustments only when LCD is ON. 45 46//backlight timing variables 47int displtime = 12000; //amount of time the display is to be on before turning off 48unsigned long displtimeon; //last recorded time display timer was reset 49int calunlock = 0; //loop counter for unlocking calibration 50 51//sensor timing variables 52unsigned long lastcheck; //last time DHT was read 53long interval = 30000; //time between DHT readings 54 55//system variables 56bool syson = true; //reference for system on/off. 57byte systog = 2; //even number toggles on, odds toggle off 58int syslock = 0; //loop counter for unlocking system toggle 59 60// █ S █ E █ T █ U █ P █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ + █ 61void setup(){ 62 63 Serial.begin(9600); //serial communication used to ensure code is working correctly. 64 65 lcd.init(); //initialize LCD 66 lcd.backlight(); //enable LCD backlight, but doesn't turn it on 67 68 lastcheck = 0; 69 digitalWrite(lcdlight, HIGH); 70 Serial.println("STARTING"); 71 lcd.print(" STARTING"); 72 73 //pin assignments 74 pinMode(calupbtn, INPUT); 75 pinMode(caldownbtn, INPUT); 76 pinMode(humidifier, OUTPUT); 77 pinMode(fan, OUTPUT); 78 pinMode(lcdlight, OUTPUT); 79 delay(1000); 80 81 82 //test fan 83 lcd.setCursor(0,1); 84 lcd.print("<FAN> HMDFR "); 85 digitalWrite(fan, LOW); 86 digitalWrite(humidifier, HIGH); 87 delay(6000); 88 //test humidifier 89 lcd.setCursor(0,1); 90 lcd.print(" FAN <HMDFR> "); 91 digitalWrite(fan, HIGH); 92 digitalWrite(humidifier, LOW); 93 delay(6000); 94 //stop startup test 95 digitalWrite(humidifier, HIGH); 96 digitalWrite(fan, HIGH); 97 lcd.clear(); 98 99 displtimeon = millis(); 100 101 int chk = DHT.read11(DHT11_PIN); 102 lastcheck = millis(); 103 104 lcd.setCursor(0,0); 105 lcd.print("Humidity: "); 106 lcd.setCursor(13,0); 107 lcd.print(DHT.humidity); 108 lcd.setCursor(15,0); 109 lcd.print("% "); 110 lcd.setCursor(0,1); 111 lcd.print("setting: "); 112 lcd.setCursor(13,1); 113 lcd.print(setpoint); 114 lcd.setCursor(15,1); 115 lcd.print("% "); 116 delay(100); 117} 118 119// █ L █ O █ O █ P █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ = █ 120void loop(){ 121 122 //check calibration buttons 123 calup = digitalRead(calupbtn); 124 caldown = digitalRead(caldownbtn); 125 126 if(calup == HIGH and caldown == HIGH){ //--------SYSTEM TOGGLE 127 syslock ++; 128 Serial.println(syslock); 129 if(syslock == 20){ //if both buttons held down for this many loops 130 systog++; 131 if(systog % 2 == 1){ //--------SYSTEM OFF 132 syson = false; 133 digitalWrite(fan, HIGH); 134 digitalWrite(humidifier, HIGH); 135 digitalWrite(lcdlight, HIGH); 136 Serial.println("SYSTEM TURNED OFF"); 137 lcd.clear(); 138 lcd.print(" SYSTEM OFF"); 139 lcd.setCursor(0,1); 140 lcd.print(" hold both btns"); 141 delay(2000); 142 lcd.setCursor(0,1); 143 lcd.print(" to turn on "); 144 displtimeon = millis(); 145 } 146 if(systog % 2 == 0){ //--------SYSTEM ON 147 syson = true; 148 Serial.println("SYSTEM TURNED ON"); 149 digitalWrite(lcdlight, HIGH); 150 lcd.clear(); 151 lcd.print(" SYSTEM ON"); 152 delay(2000); 153 lcd.clear(); 154 displtimeon = millis(); 155 } 156 syslock = 0; 157 } 158 } 159 else(syslock = 0); 160 161 //read humidity at appropriate intervals 162 if(millis() > lastcheck + interval and syson == true){ //read the DHT humidity 163 int chk = DHT.read11(DHT11_PIN); 164 lastcheck = millis(); 165 Serial.print("DHT read = "); 166 Serial.print(DHT.humidity); 167 Serial.print("%"); 168 Serial.println(" "); 169 } 170 171 //turn on the led lights when calibration buttons are pressed 172 if(calup == HIGH xor caldown == HIGH){ 173 digitalWrite(lcdlight, HIGH); 174 calstate = true; 175 displtimeon = millis(); //set display timer 176 Serial.println("cal btn ACTIVE"); 177 if(syson == false){ 178 digitalWrite(lcdlight, HIGH); 179 lcd.clear(); 180 lcd.print(" SYSTEM OFF"); 181 lcd.setCursor(0,1); 182 lcd.print(" hold both btns"); 183 delay(3000); 184 lcd.setCursor(0,1); 185 lcd.print(" to turn on "); 186 displtimeon = millis(); 187 } 188 } 189 190 if(calstate == true and syson == true){ //--------DISPLAY ROUTINE 191 Serial.println("printing display"); 192 //display variables on LCD 193 lcd.setCursor(0,0); 194 lcd.print("Humidity: "); 195 lcd.setCursor(13,0); 196 lcd.print(DHT.humidity); 197 lcd.setCursor(15,0); 198 lcd.print("% "); 199 lcd.setCursor(0,1); 200 lcd.print("setting: "); 201 lcd.setCursor(13,1); 202 lcd.print(setpoint); 203 lcd.setCursor(15,1); 204 lcd.print("% "); 205 delay(100); 206 207 calunlock ++; 208 //keeps calibration locked until display cycles 5 times after initially turned on 209 //prevents adjustments on initial button press. 210 } 211 212//--------CALIBRATION ADJUSTMENTS 213 if(calup == HIGH and caldown == LOW and calstate == true and syson == true){ 214 if(setpoint < 90 and calunlock > 5){ 215 setpoint = setpoint + 5; //increase setpoint 216 Serial.println("adj setpoint up"); 217 } 218 Serial.println(setpoint); 219 delay(100); 220 displtimeon = millis(); //reset backlight timeout 221 } 222 223 if(caldown == HIGH and calup == LOW and calstate == true and syson == true){ 224 if(setpoint > 10 and calunlock > 5){ 225 setpoint = setpoint - 5; //decrease setpoint 226 Serial.println("adj setpoint dn"); 227 } 228 Serial.println(setpoint); 229 delay(100); 230 displtimeon = millis(); //reset backlight timeout 231 } 232 233 if(millis() > displtimeon + displtime){ //-----------------BACKLIGHT TIMEOUT 234 digitalWrite(lcdlight, LOW); //turn off the screen 235 calstate = false; 236 Serial.println("displ + backlights off"); 237 lcd.clear(); 238 calunlock = 0; //lock calibration 239 } 240 241 if(millis() < lastcheck){ 242 lastcheck = millis(); //reset timers in a millisecond rollover 243 } 244 245 //--------SETPOINT ERROR PROCEDURE 246 if(setpoint > 91 or setpoint < 9){ //in case setpoint is ever out of bounds 247 Serial.println("O/B ERROR"); 248 digitalWrite(lcdlight, HIGH); 249 lcd.clear(); 250 lcd.print("O/B ERROR"); //display error message on lcd 251 lcd.setCursor(0,1); 252 lcd.print("RESETTING"); 253 delay(1000); 254 for(int count = 9; count >= 0; count = count - 1){ 255 lcd.setCursor(15,1); 256 lcd.print(count); //count down from 10 257 delay(1000); 258 } 259 setpoint = 50; //reset setpoint at 50. 260 displtimeon = millis(); 261 } 262 263 //turn on humidifier relay if below setpoint --------RELAY CONTROL 264 //RELAY MODULE IS ACTIVE LOW 265 if(DHT.humidity <= setpoint - 3 and syson == true){ //if humidity is 3% lower than setpoint 266 Serial.println("humidifier ON, fan OFF"); 267 digitalWrite(humidifier, LOW); //turn on humidifier 268 digitalWrite(fan, HIGH); 269 } 270 else if(DHT.humidity >= setpoint + 3 and syson == true){ //if humidity is 3% above setpoint 271 Serial.println("humidifier OFF, fan ON"); 272 digitalWrite(humidifier, HIGH); //turn on fan 273 digitalWrite(fan, LOW); 274 } 275 else{ 276 Serial.println("all off"); //if humidity is within 3% of setpoint 277 digitalWrite(humidifier, HIGH); //turn both off 278 digitalWrite(fan, HIGH); 279 } 280 //delay(700); //un-comment for serial debugging 281 282 Serial.print("setpoint = "); 283 Serial.println(setpoint); 284 285 //delay(700); //un-comment for serial debugging 286} 287 288/* WIRING DIAGRAMS 289 https://66.media.tumblr.com/98426b566744beacdd42bc0221092b76/tumblr_pvr0u8kvZy1yrmjh9o1_1280.png 290 */
Downloadable files
wiring diagram
wiring diagram
Comments
Only logged in users can leave comments
Anonymous user
2 years ago
Hey , i install dht.h library but i see always dht.h: No such file or directory
Anonymous user
2 years ago
Will try this fall. Im in engineering school and not only have music instruments to take care of, i think this is brilliant! Please share other ideas ....
basssman72
4 years ago
Will try this fall. Im in engineering school and not only have music instruments to take care of, i think this is brilliant! Please share other ideas ....
radiogareth
5 years ago
Thanks for sharing this project - just what I need to look after my mushroom growing cabinet :-) It won't compile in 1.81, I'm getting three errors....first error in the listing seems to be lower case on line 18 #include <dht.h> then on compiling it stops here on line 23 with 'dht does not name a type' (fair enough maybe, so changed for DHT DHT_sens(10, DHT11); from a listing that DOES work. Its a type DHT11 and its on digital pin 10. Then it stops on line 270 } else if(DHT.humidity >= setpoint + 3 and syson == true){ //if humidity is 3% above setpoint Serial.println("humidifier OFF, fan ON"); digitalWrite(humidifier, HIGH); //turn on fan digitalWrite(fan, LOW); } else{ Serial.println("all off"); //if humidity is within 3% of setpoint digitalWrite(humidifier, HIGH); //turn both off digitalWrite(fan, HIGH); } //delay(700); //un-comment for serial debugging Serial.print("setpoint = "); Serial.println(setpoint); //delay(700); //un-comment for serial debugging } UNQUOTE with the message "expected primary-expression before '.' token". Not sure why really. I'm sure I've downloaded and checked the various libraries as both my LCD and DH11 work with separate test programs. Any ideas?
radiogareth
2 years ago
I've tried the listing in the on-line compiler and it fails in the same manner and same messages as above. How did you get it to work?
Anonymous user
6 years ago
Hey , i install dht.h library but i see always dht.h: No such file or directory
auro_auro
3 months ago
Thanks for sharing this project. I'm a student of electronic engineering. I'm really interested in learning more from it. I was wondering if it would be possible for me to take a look at your PCB schematic diagram? It would be of great help for my studies.