From 6fec798425ecfcf84e3451c9262872b23e4dfb6a Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Thu, 17 Apr 2025 13:29:06 +0200 Subject: [PATCH] initial commit --- config.hpp | 54 +++++++++++++++++++++++++++++ drop.ino | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ helpers.hpp | 6 ++++ 3 files changed, 159 insertions(+) create mode 100644 config.hpp create mode 100644 drop.ino create mode 100644 helpers.hpp diff --git a/config.hpp b/config.hpp new file mode 100644 index 0000000..2c27ac0 --- /dev/null +++ b/config.hpp @@ -0,0 +1,54 @@ +#pragma once +#include + +typedef struct { + char *name; + int sensor_pin; + int valve_pin; + // define additional per-pot config here +} PotConfig; + +/// The value sensors read when completely dry +constexpr int SENSOR_CALIBRATION_DRY = 520; + +/// The value sensors read when completely wet +constexpr int SENSOR_CALIBRATION_WET = 236; + +/// Pots will always be watered below this humidity +constexpr int MIN_HUMIDITY_PERCENT = 10; + +/// Pots will never be watered above this humidity +constexpr int MAX_HUMIDITY_PERCENT = 70; + +/// the amount of time a valve needs to open/close +constexpr int VALVE_DELAY_MS = 500; + +/// the amount of time the pump needs to start/stop +constexpr int PUMP_DELAY_MS = 1000; + +/// the amount of time to water the plot (valve open and pump running) +constexpr int WATER_TIME_MS = 1500; + +/// how long to wait between loops +constexpr int LOOP_DELAY_MS = 1000; + +/// 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 + +/// 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 + +/// Per-pot configuration +constexpr PotConfig POT_CONFIGS[] = { + { + .name = "Pflanze 1", + .sensor_pin = A0, + .valve_pin = 23, // TODO + }, + { + .name = "Pflanze 2", + .sensor_pin = A1, + .valve_pin = 42, // TODO + } +}; + diff --git a/drop.ino b/drop.ino new file mode 100644 index 0000000..210d3f8 --- /dev/null +++ b/drop.ino @@ -0,0 +1,99 @@ +#include +#include "helpers.hpp" +#include "config.hpp" + +typedef struct { + PotConfig &config; + + unsigned long last_watering; + // anything changing per pot goes here +} Pot; + +Pot pots[length(POT_CONFIGS)]; + +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? + } +} + +void loop() { + for (unsigned int i = 0; i < length(pots); i++) { + per_pot(pots[i]); + } + + delay(LOOP_DELAY_MS); +} + +void per_pot(Pot &pot) { + Serial.println(pot.config.name); + + int sensorVal = analogRead(pot.config.sensor_pin); + int percentage = humidity_percentage(sensorVal); + Serial.print(sensorVal); + Serial.print(F(" -> ")); + Serial.print(percentage); + Serial.println(F("%")); + + if (percentage > MAX_HUMIDITY_PERCENT) { + Serial.println(F("too wet -> not watering")); + } else if (pot.last_watering + MIN_WATERING_INTERVAL_MS > millis()) { + Serial.println(F("watered recently -> 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) { + open_valve(pot.config.valve_pin); + start_pump(); + delay(WATER_TIME_MS); + stop_pump(); + close_valve(pot.config.valve_pin); + pot.last_watering = millis(); +} + +int humidity_percentage(int sensorValue) { + // Sensor has a range of 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); +} + +void start_pump() { + // TODO start pump + 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 + delay(VALVE_DELAY_MS); +} \ No newline at end of file diff --git a/helpers.hpp b/helpers.hpp new file mode 100644 index 0000000..7f01022 --- /dev/null +++ b/helpers.hpp @@ -0,0 +1,6 @@ +#pragma once + +/// returns the amount of elements in an array +template constexpr int length(T arr[]) { + return sizeof(arr) / sizeof(T); +}