#include "config.hpp" /// a connected pot typedef struct { PotConfig *config; unsigned long last_watering; // anything changing per pot goes here } Pot; /// all connected pots Pot pots[POT_COUNT]; void setup() { Serial.begin(9600); Serial.println(""); Serial.println("Initializing..."); pinMode(PUMP_LED_PIN, OUTPUT); pinMode(PUMP_PIN, OUTPUT); pinMode(LED_BUILTIN, OUTPUT); pinMode(OK_LED_PIN, OUTPUT); set_pump(false); // link pots to their config for (unsigned int i = 0; i < POT_COUNT; i++) { Pot *pot = &pots[i]; pot->config = &POT_CONFIGS[i]; pot->last_watering = 0; pinMode(pot->config->valve_pin, OUTPUT); pinMode(pot->config->led_pin, OUTPUT); set_valve(pot->config->valve_pin, false); } } void loop() { Serial.println(""); Serial.println("LOOP"); digitalWrite(OK_LED_PIN, HIGH); delay(100); digitalWrite(OK_LED_PIN, LOW); for (unsigned int i = 0; i < POT_COUNT; i++) { Serial.print("Pot "); Serial.println(i); per_pot(pots[i]); Serial.println(""); } delay(LOOP_DELAY_MS); } void per_pot(Pot &pot) { if (pot.last_watering + MIN_WATERING_INTERVAL_MS > millis()) { Serial.println(F("watered recently -> not watering")); return; } int percentage = get_humidity(pot.config->sensor); if (percentage > MAX_HUMIDITY_PERCENT) { Serial.println(F("too wet -> not watering")); } else if (percentage < MIN_HUMIDITY_PERCENT) { Serial.println(F("too dry -> watering")); water_pot(pot); } else if (pot.last_watering + MAX_WATERING_INTERVAL_MS < millis()) { Serial.println(F("not been watered for a long time -> watering")); water_pot(pot); } else { Serial.println(F("happy plant")); } } void water_pot(Pot &pot) { digitalWrite(LED_BUILTIN, HIGH); digitalWrite(pot.config->led_pin, HIGH); set_valve(pot.config->valve_pin, HIGH); set_pump(HIGH); delay(WATER_TIME_MS); pot.last_watering = millis(); set_pump(LOW); set_valve(pot.config->valve_pin, LOW); digitalWrite(pot.config->led_pin, LOW); digitalWrite(LED_BUILTIN, LOW); } /// get humidity sensor value as a percentage int get_humidity(Sensor &sensor) { // take average of multiple measurements int sensorVal {0}; for (unsigned int i = 0; i < MEASUREMENT_COUNT; i++) { sensorVal += analogRead(sensor.pin); Serial.print(F("Measurement ")); Serial.print(i); Serial.print(F(" = ")); Serial.println(sensorVal); delay(MEASUREMENT_DELAY); } sensorVal /= MEASUREMENT_COUNT; Serial.print(F("Average: ")); Serial.println(sensorVal); // Sensor has a range of e.g. 236 to 520 // We want to translate this to a scale or 0% to 100% // More info: https://www.arduino.cc/reference/en/language/functions/math/map/ sensorVal = map(sensorVal, sensor.calibration_wet, sensor.calibration_dry, 100, 0); Serial.print(F("Humidity: ")); Serial.print(sensorVal); Serial.println(F("%")); return sensorVal; } void set_pump(bool on) { Serial.print("setting pump to state "); Serial.println(on); digitalWrite(PUMP_LED_PIN, on ? HIGH : LOW); digitalWrite(PUMP_PIN, on ? LOW : HIGH); delay(PUMP_DELAY_MS); } void set_valve(uint8_t valve, bool open) { Serial.print("setting valve on pin "); Serial.print(valve); Serial.print(" to state "); Serial.println(open); digitalWrite(valve, open ? LOW : HIGH); delay(VALVE_DELAY_MS); }