#include #include #include const char* ssid = "OpenWrt"; const char* password = "La1003000902"; WebServer server(80); const int motorPin = 11; // Change this to the pin number connected to the motor relay const int sensorPin = 16; // Change this to the pin number connected to the moisture sensor //storage void writeLongToEEPROM(int address, long value) { // write the four bytes of the long integer to EEPROM EEPROM.write(address, (value >> 24) & 0xFF); EEPROM.write(address + 1, (value >> 16) & 0xFF); EEPROM.write(address + 2, (value >> 8) & 0xFF); EEPROM.write(address + 3, value & 0xFF); EEPROM.commit(); } long readLongFromEEPROM(int address) { // read the four bytes of the long integer from EEPROM byte b1 = EEPROM.read(address); byte b2 = EEPROM.read(address + 1); byte b3 = EEPROM.read(address + 2); byte b4 = EEPROM.read(address + 3); // combine the four bytes to form a long integer long value = ((long)b1 << 24) | ((long)b2 << 16) | ((long)b3 << 8) | (long)b4; return value; } //moisture const int maxAnalogValue = 80000; const int numReadings = 10; // Number of readings to average int readings[numReadings]; // Array to store readings int readingIndex = 0; // Current index in array int total = 0; // Running total of readings from history int moisture = 0; //current calculated moisture level int getMoisture(){ //motor is messing with readings bool mot = getMotor(); setMotor(true); delay(10); // Read the sensor value and add it to the total total -= readings[readingIndex]; readings[readingIndex] = analogRead(sensorPin); total += readings[readingIndex]; // Move to the next index in the array readingIndex = (readingIndex + 1) % numReadings; // Calculate the average value moisture = total / numReadings; setMotor(mot); return moisture; } int getMoisturePercent(){ int m = getMoisture(); //TODO:fix percentage calculation m = map(m,0,8000,0,100); return m; } //desired moisture int desiredMoisture; // The desired moisture level const int desiredMoistureAddress = 0; // Address to store the desired moisture level in EEPROM void setDesiredMoisture(int m){ if (abs(m - desiredMoisture) >= 50) { desiredMoisture = m; writeLongToEEPROM(desiredMoistureAddress, desiredMoisture); } } void setDesiredMoisturePercent(int m){ //todo map from percent setDesiredMoisture(m); } int getDesiredMoisture(){ desiredMoisture = readLongFromEEPROM(desiredMoistureAddress); return desiredMoisture; } int getDesiredMoisturePercent(){ int m = getDesiredMoisturePercent(); //todo map return m; } //motor bool motorSpinning = false; void setMotor(bool state){ state = state; //add a ! if need to invert command digitalWrite(motorPin, state); motorSpinning = state; } bool getMotor(){ return motorSpinning; } //trigger watering void waterTrigger(){ // Add some wiggle room to the desired moisture level int d = getDesiredMoisture(); int m = getMoisture(); bool mot = getMotor(); int threshold = d * 0.1; int lowerThreshold = d - threshold; int upperThreshold = d + threshold; // Check if the moisture level is below the lower threshold if (m < lowerThreshold) { if (!mot){ setMotor(true); } } // Check if the moisture level is above the upper threshold else if (m > upperThreshold) { if (mot){ setMotor(false); } } } //Webinterface void webserver() { String html = "Moisture Control"; //script html += ""; //html html += ""; html += "

Moisture Control

"; html += "

Moisture: "+String( getMoisture())+"

"; html += "

Desired Moisture: "+String( getDesiredMoisture())+"

"; html += "

Pumps running: "+String(getMotor())+"

"; html += ""; html += ""; html += "

Set new target for desired moisture:"; html += "
"; html += ""; html += ""; //style html += ""; server.send(200, "text/html", html); } void webserverMoisture() { String response = String(moisture); server.send(200, "text/plain", response); } void webserverDesiredMoisture() { if (server.hasArg("desiredMoisture")) { int newDesiredMoisture = server.arg("desiredMoisture").toInt(); setDesiredMoisture(newDesiredMoisture); String response = String(getDesiredMoisture()); server.send(200, "text/plain", response); } else { String response = String(getDesiredMoisture()); server.send(200, "text/plain", response); } } void webserverPump() { if (server.hasArg("set")) { int setMotorsWeb = server.arg("set").toInt(); //TODO: add write pump status if (setMotorsWeb == 1){ setMotor(true); }else if (setMotorsWeb == 0){ setMotor(false); } server.send(200, "text/plain", "OK"); } else { String response = String(getMotor()); server.send(200, "text/plain", response); } } void setup() { Serial.begin(115200); pinMode(motorPin, OUTPUT); digitalWrite(motorPin, LOW); //not really needed pinMode(12, OUTPUT); digitalWrite(12, LOW); pinMode(sensorPin, INPUT); // Read the desired moisture level from EEPROM address 0 EEPROM.begin(128); desiredMoisture = readLongFromEEPROM(0); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); server.on("/", webserver); server.on("/moisture", webserverMoisture); server.on("/desired-moisture", webserverDesiredMoisture); server.on("/pump", webserverPump); server.begin(); } unsigned long previousMillis = 0; const long interval = 1000; // interval in milliseconds void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { // save the last time you blinked the LED previousMillis = currentMillis; waterTrigger(); } server.handleClient(); }