diff --git a/config.hpp b/config.hpp index 2c27ac0..e382796 100644 --- a/config.hpp +++ b/config.hpp @@ -2,17 +2,26 @@ #include typedef struct { - char *name; - int sensor_pin; - int valve_pin; + uint8_t pin; + /// The value sensors read when completely dry + int calibration_dry; + /// The value sensors read when completely wet + int calibration_wet; +} Sensor; + +typedef struct { + uint8_t valve_pin; + uint8_t led_pin; + Sensor sensor; // define additional per-pot config here } PotConfig; -/// The value sensors read when completely dry -constexpr int SENSOR_CALIBRATION_DRY = 520; +constexpr unsigned int SECOND = 1000; +constexpr unsigned int MINUTE = SECOND * 60; +constexpr unsigned int HOUR = MINUTE * 60; -/// The value sensors read when completely wet -constexpr int SENSOR_CALIBRATION_WET = 236; +constexpr unsigned int MEASUREMENT_COUNT = 3; +constexpr int MEASUREMENT_DELAY = 10; /// Pots will always be watered below this humidity constexpr int MIN_HUMIDITY_PERCENT = 10; @@ -21,34 +30,47 @@ constexpr int MIN_HUMIDITY_PERCENT = 10; constexpr int MAX_HUMIDITY_PERCENT = 70; /// the amount of time a valve needs to open/close -constexpr int VALVE_DELAY_MS = 500; +constexpr int VALVE_DELAY_MS = 1 * SECOND; /// the amount of time the pump needs to start/stop -constexpr int PUMP_DELAY_MS = 1000; +constexpr int PUMP_DELAY_MS = 1 * SECOND; /// the amount of time to water the plot (valve open and pump running) -constexpr int WATER_TIME_MS = 1500; +constexpr int WATER_TIME_MS = 3 * SECOND; /// how long to wait between loops -constexpr int LOOP_DELAY_MS = 1000; +constexpr int LOOP_DELAY_MS = 1 * SECOND; // TODO set higher once it is working /// minimum amount of time to wait between watering each pot, even when minimum wetness has been reached -constexpr int MIN_WATERING_INTERVAL_MS = 1000 * 60; // 1 min +constexpr int MIN_WATERING_INTERVAL_MS = 1 * MINUTE; /// maximum amount of time to wait between watering each pot, as long as maximum wetness has not been reaached -constexpr int MAX_WATERING_INTERVAL_MS = 1000 * 60 * 60 * 24; // 1 day +constexpr int MAX_WATERING_INTERVAL_MS = 24 * HOUR; + +constexpr uint8_t PUMP_PIN = 22; +constexpr uint8_t PUMP_LED_PIN = 23; /// Per-pot configuration constexpr PotConfig POT_CONFIGS[] = { { - .name = "Pflanze 1", - .sensor_pin = A0, - .valve_pin = 23, // TODO + .valve_pin = 2, + .led_pin = 42, + .sensor = { + .pin = A0, + .calibration_dry = 520, + .calibration_wet = 236, + } }, { - .name = "Pflanze 2", - .sensor_pin = A1, - .valve_pin = 42, // TODO - } + .valve_pin = 3, + .led_pin = 43, + .sensor = { + .pin = A1, + .calibration_dry = 520, + .calibration_wet = 236, + } + }, }; +constexpr unsigned int POT_COUNT = sizeof(POT_CONFIGS) / sizeof(POT_CONFIGS[0]); + diff --git a/drop.ino b/drop.ino index 210d3f8..50f38bf 100644 --- a/drop.ino +++ b/drop.ino @@ -1,49 +1,43 @@ -#include -#include "helpers.hpp" #include "config.hpp" +/// a connected pot typedef struct { - PotConfig &config; - + PotConfig *config; + unsigned long last_watering; // anything changing per pot goes here } Pot; -Pot pots[length(POT_CONFIGS)]; +/// all connected pots +Pot pots[POT_COUNT]; void setup() { Serial.begin(9600); - pinMode(6, OUTPUT); //Enable - pinMode(5, OUTPUT); //Puls - pinMode(13, OUTPUT); //Status LED - pinMode(4, OUTPUT); //Enable6 halten - pinMode(2, OUTPUT); //Puls5- - pinMode(3, OUTPUT); //Direction4- - - // link pots to their config - for (unsigned int i = 0; i < length(pots); i++) { - pots[i].config = POT_CONFIGS[i]; - - // TODO maybe set pinMode for valve and sensor pins? - } + pinMode(PUMP_LED_PIN, OUTPUT); + pinMode(PUMP_PIN, OUTPUT); } void loop() { - for (unsigned int i = 0; i < length(pots); i++) { + Serial.println("LOOP"); + + 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) { - Serial.println(pot.config.name); + int percentage = get_humidity(pot.config->sensor); + if (percentage < 0) { + Serial.println(F("sensor not connected")); + return; + } - int sensorVal = analogRead(pot.config.sensor_pin); - int percentage = humidity_percentage(sensorVal); - Serial.print(sensorVal); - Serial.print(F(" -> ")); Serial.print(percentage); Serial.println(F("%")); @@ -54,7 +48,7 @@ void per_pot(Pot &pot) { } 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()){ + } 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 { @@ -63,37 +57,45 @@ void per_pot(Pot &pot) { } void water_pot(Pot &pot) { - open_valve(pot.config.valve_pin); - start_pump(); + digitalWrite(pot.config->led_pin, HIGH); + + set_valve(pot.config->valve_pin, HIGH); + set_pump(HIGH); + delay(WATER_TIME_MS); - stop_pump(); - close_valve(pot.config.valve_pin); pot.last_watering = millis(); + + set_pump(LOW); + set_valve(pot.config->valve_pin, LOW); + + digitalWrite(pot.config->led_pin, LOW); } -int humidity_percentage(int sensorValue) { - // Sensor has a range of 236 to 520 +/// 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.println(sensorVal); + delay(MEASUREMENT_DELAY); + } + + sensorVal /= MEASUREMENT_COUNT; + + // 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/ - return map(sensorValue, SENSOR_CALIBRATION_WET, SENSOR_CALIBRATION_DRY, 100, 0); + return map(sensorVal, sensor.calibration_wet, sensor.calibration_dry, 100, 0); } -void start_pump() { - // TODO start pump +void set_pump(uint8_t state) { + digitalWrite(PUMP_LED_PIN, state); + digitalWrite(PUMP_PIN, state); delay(PUMP_DELAY_MS); } -void stop_pump() { - // TODO stop pump - delay(PUMP_DELAY_MS); -} - -void open_valve(int valve) { - // TODO open valve - delay(VALVE_DELAY_MS); -} - -void close_valve(int valve) { - // TODO close valve +void set_valve(uint8_t valve, uint8_t state) { + digitalWrite(valve, state); delay(VALVE_DELAY_MS); } \ No newline at end of file diff --git a/helpers.hpp b/helpers.hpp deleted file mode 100644 index 7f01022..0000000 --- a/helpers.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -/// returns the amount of elements in an array -template constexpr int length(T arr[]) { - return sizeof(arr) / sizeof(T); -}