My not so stupid home
Control and read light, temperature, humidity, feeder and water pump for cat with SD card, HTTP server on NodeMcu and Android client app.
Devices & Components
Arduino Uno Rev3
SG90 Micro-servo motor
Android phone
Jumper wires (generic)
Dual H-Bridge motor drivers L298
DHT11 Temperature & Humidity Sensor (4 pins)
NodeMCU ESP8266 Breakout Board
DC motor (generic)
Relay Module (Generic)
LED Light Bulb, Frosted GLS
60W PCIe 12V 5A Power Supply
Hardware & Tools
SD Card module
Software & Tools
Arduino IDE
Visual Studio 2017
Project description
Code
Android application code
Time.cpp
c_cpp
1#include "Time.h" 2 3Time::Time() 4{ 5 _hours = -1; 6 _minutes = -1; 7 _seconds = -1; 8 9} 10 11Time::Time(int hours, int minutes, int seconds) 12{ 13 _hours = hours; 14 _minutes = minutes; 15 _seconds = seconds; 16 17} 18 19String Time::toString(){ 20 return String(_hours)+":"+ String(_minutes)+":"+String(_seconds); 21} 22int Time::getHours() 23{ 24 return _hours; 25} 26 27int Time::getMinutes() 28{ 29 return _minutes; 30} 31 32int Time::getSeconds() 33{ 34 return _seconds; 35} 36 37void Time::setHours(int hours) 38{ 39 _hours=hours; 40} 41 42void Time::setMinutes(int minutes) 43{ 44 _minutes=minutes; 45} 46 47void Time::setSeconds(int seconds) 48{ 49 _seconds=seconds; 50} 51 52bool Time::isEqual(Time t) 53{ 54 if( _hours == t.getHours() && 55 _minutes == t.getMinutes() && 56 _seconds == t.getSeconds() 57 ) 58 { 59 return true; 60 } 61 else 62 { 63 return false; 64 } 65}
MyNotSoStupidHomeHttp.ino
arduino
1#include <ArduinoJson.h> 2#include <Servo.h> 3#include <ESP8266WebServer.h> 4#include <ESP8266mDNS.h> 5#include <DHT.h> 6#include <SPI.h> 7#include <SD.h> 8#include <WiFiUdp.h> 9#include <NTPClient.h> 10#include "Time.h" 11File myFile; 12 13#define DHTTYPE DHT11 14 15//DHT11 sensor pin 16#define DHTPin 3 //RX pin 17 18// Water pump pins 19#define ENBPin 2 // D4 20#define IN3Pin 4 // D2 21#define IN4Pin 0 // D3 22 23//Servo pin 24#define SERVOPin 5 //D1 25 26// Light relay pin 27#define LIGHTPin 16 //D0 28 29//SD card 30const int chipSelect = D8; // used for ESP8266 31 32//WiFi 33const char* ssid = "wifiname"; 34const char* password = "password"; 35 36//UTC + offset 37const long utcOffsetInSeconds = 3600; 38 39ESP8266WebServer server(80); 40DHT dht(DHTPin, DHTTYPE); 41 42Servo servo1; 43 44WiFiUDP ntpUDP; 45NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", utcOffsetInSeconds); 46 47 48//Time 49Time feedingTime; 50Time wateringTime; 51 52static float celsiusTemp; 53static float humidityTemp; 54static int lightState; 55 56void setup() { 57 Serial.begin(115200); 58 // startTime = millis(); 59 servo1.attach(SERVOPin); 60 dht.begin(); 61 62 // Initialize the output variables as outputs 63 pinMode(LIGHTPin, OUTPUT); 64 pinMode(IN3Pin, OUTPUT); 65 pinMode(IN4Pin, OUTPUT); 66 pinMode(ENBPin, OUTPUT); 67 68 // Set outputs to LOW 69 digitalWrite(LIGHTPin, LOW); 70 readConfig(); 71 connectAndStartServer(); 72} 73 74void readConfig() { 75 if (!SD.begin(chipSelect)) { 76 Serial.println("Initialization failed!"); 77 while (1); 78 } 79 80 String data =""; 81 File dataFile = SD.open("config.json",FILE_READ); 82 83 if (dataFile) { 84 85 while (dataFile.available()) 86 { 87 data += (char)dataFile.read(); 88 } 89 dataFile.close(); 90 91 StaticJsonDocument<200> doc; 92 deserializeJson(doc, data); 93 //Set watering time 94 wateringTime.setHours((int)doc["wateringTime"]["hours"]); 95 wateringTime.setMinutes((int)doc["wateringTime"]["minnutes"]); 96 wateringTime.setSeconds((int)doc["wateringTime"]["seconds"]); 97 98 //Set feeding time 99 feedingTime.setHours((int)doc["feedingTime"]["hours"]); 100 feedingTime.setMinutes((int)doc["feedingTime"]["minnutes"]); 101 feedingTime.setSeconds((int)doc["feedingTime"]["seconds"]); 102 } 103} 104void connectAndStartServer(){ 105 // Connect to Wi-Fi network with SSID and password 106 Serial.print("Connecting to "); 107 Serial.println(ssid); 108 WiFi.begin(ssid, password); 109 while (WiFi.status() != WL_CONNECTED) { 110 delay(500); 111 Serial.print("."); 112 } 113 114 // Print local IP address and start web server 115 Serial.println(""); 116 Serial.println("WiFi connected."); 117 Serial.println("IP address: "); 118 Serial.println(WiFi.localIP()); 119 120 // Server GET and POST methods 121 server.on("/", handleRoot); 122 server.on("/getTemperatureAndHumidity", handleTemperatureAndHumidity); 123 server.on("/setLightState/",handleLightState); 124 server.on("/startWatering",handlePump); 125 server.on("/startFeeding",handleFeeder); 126 server.on("/getConfiguration",handleGetConfiguration); 127 server.onNotFound(handleNotFound); 128 129 server.begin(); 130 131 Serial.println("HTTP server started"); 132} 133 134void handleGetConfiguration(){ 135 String data =""; 136 File dataFile = SD.open("config.json",FILE_READ); 137 138 if (dataFile) { 139 140 while (dataFile.available()) 141 { 142 data += (char)dataFile.read(); 143 } 144 dataFile.close(); 145 146 server.send(200,"application/json",data); 147 } 148 else 149 { 150 server.send(400,"error with Sd card"); 151 } 152} 153 154void handleFeeder(){ 155 servo1.write(0); 156 delay(500); 157 servo1.write(90); 158 delay(500); 159 servo1.write(0); 160 delay(500); 161 162 server.send(200,"text/plain","Feeding done"); 163} 164void handleLightState(){ 165 String message = ""; 166 if (server.method() != HTTP_POST) { 167 Serial.println("Not allowed."); 168 server.send(405, "text/plain", "Method Not Allowed"); 169 } 170 else 171 { 172 String state = server.arg("plain"); 173 SetLight(state.toInt()); 174 server.send(200, "application/json", "{\\"lightState\\":" + state +"}"); 175 } 176} 177void handleTemperatureAndHumidity(){ 178 if(ReadDHT11()) 179 { 180 server.send(200,"application/json","{\\"temperature\\":"+ String(celsiusTemp) +",\\"humidity\\":"+ String(humidityTemp) +"}"); 181 } 182 else 183 { 184 server.send(400,"text/plain","Unable to read from sensor"); 185 } 186 187} 188void handleRoot(){ 189 ReadDHT11(); 190 server.send(200,"application/json","{\\"temperature\\":"+ String(celsiusTemp) +",\\"humidity\\":"+ String(humidityTemp) +",\\"lightState\\":"+ String(lightState) +"}"); 191} 192void handleNotFound() { 193 194 String message = "File Not Found\ 195\ 196"; 197 message += "URI: "; 198 message += server.uri(); 199 message += "\ 200Method: "; 201 message += (server.method() == HTTP_GET) ? "GET" : "POST"; 202 message += "\ 203Arguments: "; 204 message += server.args(); 205 message += "\ 206"; 207 208 for (uint8_t i = 0; i < server.args(); i++) { 209 message += " " + server.argName(i) + ": " + server.arg(i) + "\ 210"; 211 } 212 213 server.send(404, "text/plain", message); 214} 215void handlePump(){ 216 // Run water pump 217 digitalWrite(IN3Pin, LOW); 218 digitalWrite(IN4Pin, HIGH); 219 digitalWrite(ENBPin, HIGH); 220 221 // Make pump run for 6 sec. 222 Serial.println("Watering.."); 223 delay(6000); 224 225 // Stop pump 226 digitalWrite(IN3Pin, LOW); 227 digitalWrite(IN4Pin, LOW); 228 digitalWrite(ENBPin, LOW); 229 230 Serial.println("Watering done."); 231 232 server.send(200,"text/plain","Watering done"); 233} 234 235void loop(void) { 236 server.handleClient(); 237 MDNS.update(); 238 getTime(); 239} 240void getTime() { 241 timeClient.update(); 242 int hours = timeClient.getHours(); 243 int minutes = timeClient.getMinutes(); 244 int seconds = timeClient.getSeconds(); 245 //use 246 handleTime(Time(hours,minutes,seconds)); 247 delay(1000); 248} 249void handleTime(Time t){ 250 if(t.isEqual(feedingTime)) 251 { 252 handleFeeder(); 253 } 254 if(t.isEqual(wateringTime)) 255 { 256 handlePump(); 257 } 258} 259 260void SetLight(int state){ 261 digitalWrite(LIGHTPin, state); 262 lightState = state; 263} 264 265bool ReadDHT11(){ 266 267 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 268 float h = dht.readHumidity(); 269 // Read temperature as Celsius (the default) 270 float t = dht.readTemperature(); 271 272 // Check if any reads failed and exit early (to try again). 273 if (isnan(h) || isnan(t)) { 274 Serial.println("Failed to read from DHT sensor!"); 275 celsiusTemp = 0; 276 humidityTemp = 0; 277 return false; 278 } 279 else{ 280 // Computes temperature values in Celsius + Fahrenheit and Humidity 281 celsiusTemp = t; 282 humidityTemp = h; 283 return true; 284 } 285 286}
MyNotSoStupidHomeHttp GitHub
Time.h
h
1#ifndef Time_h 2#define Time_h 3 4#include <Arduino.h> 5 6class Time 7{ 8 public: 9 Time(); 10 Time(int hours, int minutes, int seconds); 11 int getHours(); 12 int getMinutes(); 13 int getSeconds(); 14 void setHours(int hours); 15 void setMinutes(int minutes); 16 void setSeconds(int seconds); 17 bool isEqual(Time t); 18 String toString(); 19 20 private: 21 int _hours; 22 int _minutes; 23 int _seconds; 24}; 25 26#endif
Time.h
h
1#ifndef Time_h 2#define Time_h 3 4#include <Arduino.h> 5 6class 7 Time 8{ 9 public: 10 Time(); 11 Time(int hours, int minutes, int seconds); 12 13 int getHours(); 14 int getMinutes(); 15 int getSeconds(); 16 void 17 setHours(int hours); 18 void setMinutes(int minutes); 19 void setSeconds(int 20 seconds); 21 bool isEqual(Time t); 22 String toString(); 23 24 private: 25 26 int _hours; 27 int _minutes; 28 int _seconds; 29}; 30 31#endif
Time.cpp
c_cpp
1#include "Time.h" 2 3Time::Time() 4{ 5 _hours = -1; 6 _minutes = -1; 7 _seconds = -1; 8 9} 10 11Time::Time(int hours, int minutes, int seconds) 12{ 13 _hours = hours; 14 _minutes = minutes; 15 _seconds = seconds; 16 17} 18 19String Time::toString(){ 20 return String(_hours)+":"+ String(_minutes)+":"+String(_seconds); 21} 22int Time::getHours() 23{ 24 return _hours; 25} 26 27int Time::getMinutes() 28{ 29 return _minutes; 30} 31 32int Time::getSeconds() 33{ 34 return _seconds; 35} 36 37void Time::setHours(int hours) 38{ 39 _hours=hours; 40} 41 42void Time::setMinutes(int minutes) 43{ 44 _minutes=minutes; 45} 46 47void Time::setSeconds(int seconds) 48{ 49 _seconds=seconds; 50} 51 52bool Time::isEqual(Time t) 53{ 54 if( _hours == t.getHours() && 55 _minutes == t.getMinutes() && 56 _seconds == t.getSeconds() 57 ) 58 { 59 return true; 60 } 61 else 62 { 63 return false; 64 } 65}
MyNotSoStupidHomeHttp.ino
arduino
1#include <ArduinoJson.h> 2#include <Servo.h> 3#include <ESP8266WebServer.h> 4#include <ESP8266mDNS.h> 5#include <DHT.h> 6#include <SPI.h> 7#include <SD.h> 8#include <WiFiUdp.h> 9#include <NTPClient.h> 10#include "Time.h" 11File myFile; 12 13#define DHTTYPE DHT11 14 15//DHT11 sensor pin 16#define DHTPin 3 //RX pin 17 18// Water pump pins 19#define ENBPin 2 // D4 20#define IN3Pin 4 // D2 21#define IN4Pin 0 // D3 22 23//Servo pin 24#define SERVOPin 5 //D1 25 26// Light relay pin 27#define LIGHTPin 16 //D0 28 29//SD card 30const int chipSelect = D8; // used for ESP8266 31 32//WiFi 33const char* ssid = "wifiname"; 34const char* password = "password"; 35 36//UTC + offset 37const long utcOffsetInSeconds = 3600; 38 39ESP8266WebServer server(80); 40DHT dht(DHTPin, DHTTYPE); 41 42Servo servo1; 43 44WiFiUDP ntpUDP; 45NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", utcOffsetInSeconds); 46 47 48//Time 49Time feedingTime; 50Time wateringTime; 51 52static float celsiusTemp; 53static float humidityTemp; 54static int lightState; 55 56void setup() { 57 Serial.begin(115200); 58 // startTime = millis(); 59 servo1.attach(SERVOPin); 60 dht.begin(); 61 62 // Initialize the output variables as outputs 63 pinMode(LIGHTPin, OUTPUT); 64 pinMode(IN3Pin, OUTPUT); 65 pinMode(IN4Pin, OUTPUT); 66 pinMode(ENBPin, OUTPUT); 67 68 // Set outputs to LOW 69 digitalWrite(LIGHTPin, LOW); 70 readConfig(); 71 connectAndStartServer(); 72} 73 74void readConfig() { 75 if (!SD.begin(chipSelect)) { 76 Serial.println("Initialization failed!"); 77 while (1); 78 } 79 80 String data =""; 81 File dataFile = SD.open("config.json",FILE_READ); 82 83 if (dataFile) { 84 85 while (dataFile.available()) 86 { 87 data += (char)dataFile.read(); 88 } 89 dataFile.close(); 90 91 StaticJsonDocument<200> doc; 92 deserializeJson(doc, data); 93 //Set watering time 94 wateringTime.setHours((int)doc["wateringTime"]["hours"]); 95 wateringTime.setMinutes((int)doc["wateringTime"]["minnutes"]); 96 wateringTime.setSeconds((int)doc["wateringTime"]["seconds"]); 97 98 //Set feeding time 99 feedingTime.setHours((int)doc["feedingTime"]["hours"]); 100 feedingTime.setMinutes((int)doc["feedingTime"]["minnutes"]); 101 feedingTime.setSeconds((int)doc["feedingTime"]["seconds"]); 102 } 103} 104void connectAndStartServer(){ 105 // Connect to Wi-Fi network with SSID and password 106 Serial.print("Connecting to "); 107 Serial.println(ssid); 108 WiFi.begin(ssid, password); 109 while (WiFi.status() != WL_CONNECTED) { 110 delay(500); 111 Serial.print("."); 112 } 113 114 // Print local IP address and start web server 115 Serial.println(""); 116 Serial.println("WiFi connected."); 117 Serial.println("IP address: "); 118 Serial.println(WiFi.localIP()); 119 120 // Server GET and POST methods 121 server.on("/", handleRoot); 122 server.on("/getTemperatureAndHumidity", handleTemperatureAndHumidity); 123 server.on("/setLightState/",handleLightState); 124 server.on("/startWatering",handlePump); 125 server.on("/startFeeding",handleFeeder); 126 server.on("/getConfiguration",handleGetConfiguration); 127 server.onNotFound(handleNotFound); 128 129 server.begin(); 130 131 Serial.println("HTTP server started"); 132} 133 134void handleGetConfiguration(){ 135 String data =""; 136 File dataFile = SD.open("config.json",FILE_READ); 137 138 if (dataFile) { 139 140 while (dataFile.available()) 141 { 142 data += (char)dataFile.read(); 143 } 144 dataFile.close(); 145 146 server.send(200,"application/json",data); 147 } 148 else 149 { 150 server.send(400,"error with Sd card"); 151 } 152} 153 154void handleFeeder(){ 155 servo1.write(0); 156 delay(500); 157 servo1.write(90); 158 delay(500); 159 servo1.write(0); 160 delay(500); 161 162 server.send(200,"text/plain","Feeding done"); 163} 164void handleLightState(){ 165 String message = ""; 166 if (server.method() != HTTP_POST) { 167 Serial.println("Not allowed."); 168 server.send(405, "text/plain", "Method Not Allowed"); 169 } 170 else 171 { 172 String state = server.arg("plain"); 173 SetLight(state.toInt()); 174 server.send(200, "application/json", "{\\"lightState\\":" + state +"}"); 175 } 176} 177void handleTemperatureAndHumidity(){ 178 if(ReadDHT11()) 179 { 180 server.send(200,"application/json","{\\"temperature\\":"+ String(celsiusTemp) +",\\"humidity\\":"+ String(humidityTemp) +"}"); 181 } 182 else 183 { 184 server.send(400,"text/plain","Unable to read from sensor"); 185 } 186 187} 188void handleRoot(){ 189 ReadDHT11(); 190 server.send(200,"application/json","{\\"temperature\\":"+ String(celsiusTemp) +",\\"humidity\\":"+ String(humidityTemp) +",\\"lightState\\":"+ String(lightState) +"}"); 191} 192void handleNotFound() { 193 194 String message = "File Not Found\ 195\ 196"; 197 message += "URI: "; 198 message += server.uri(); 199 message += "\ 200Method: "; 201 message += (server.method() == HTTP_GET) ? "GET" : "POST"; 202 message += "\ 203Arguments: "; 204 message += server.args(); 205 message += "\ 206"; 207 208 for (uint8_t i = 0; i < server.args(); i++) { 209 message += " " + server.argName(i) + ": " + server.arg(i) + "\ 210"; 211 } 212 213 server.send(404, "text/plain", message); 214} 215void handlePump(){ 216 // Run water pump 217 digitalWrite(IN3Pin, LOW); 218 digitalWrite(IN4Pin, HIGH); 219 digitalWrite(ENBPin, HIGH); 220 221 // Make pump run for 6 sec. 222 Serial.println("Watering.."); 223 delay(6000); 224 225 // Stop pump 226 digitalWrite(IN3Pin, LOW); 227 digitalWrite(IN4Pin, LOW); 228 digitalWrite(ENBPin, LOW); 229 230 Serial.println("Watering done."); 231 232 server.send(200,"text/plain","Watering done"); 233} 234 235void loop(void) { 236 server.handleClient(); 237 MDNS.update(); 238 getTime(); 239} 240void getTime() { 241 timeClient.update(); 242 int hours = timeClient.getHours(); 243 int minutes = timeClient.getMinutes(); 244 int seconds = timeClient.getSeconds(); 245 //use 246 handleTime(Time(hours,minutes,seconds)); 247 delay(1000); 248} 249void handleTime(Time t){ 250 if(t.isEqual(feedingTime)) 251 { 252 handleFeeder(); 253 } 254 if(t.isEqual(wateringTime)) 255 { 256 handlePump(); 257 } 258} 259 260void SetLight(int state){ 261 digitalWrite(LIGHTPin, state); 262 lightState = state; 263} 264 265bool ReadDHT11(){ 266 267 // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 268 float h = dht.readHumidity(); 269 // Read temperature as Celsius (the default) 270 float t = dht.readTemperature(); 271 272 // Check if any reads failed and exit early (to try again). 273 if (isnan(h) || isnan(t)) { 274 Serial.println("Failed to read from DHT sensor!"); 275 celsiusTemp = 0; 276 humidityTemp = 0; 277 return false; 278 } 279 else{ 280 // Computes temperature values in Celsius + Fahrenheit and Humidity 281 celsiusTemp = t; 282 humidityTemp = h; 283 return true; 284 } 285 286}
MyNotSoStupidHomeHttp GitHub
Android application code
Downloadable files
Fritzing schematic
Fritzing schematic
Fritzing schematic
Fritzing schematic
Fritzing image
Fritzing image

Comments
Only logged in users can leave comments