#include <Streaming.h>
Print& cout {Serial};
// Automatically define a suitable data type for millis()
using Millis_t = decltype(millis());
constexpr Millis_t gcBlinkInterval {500};
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const Millis_t duration) const { return (millis() - timeStamp >= duration); }
private:
Millis_t timeStamp {0};
};
// Define new own data type for moisture sensor
struct SensorDevice {
const uint8_t pin;
const int threshold;
const Millis_t delay_ms;
};
// Define new own data type for a watering pump
struct PumpDevice {
const uint8_t pin;
const Millis_t delay_ms;
bool isRunning;
};
SensorDevice sensor {A0, 500, 15000}; // Init. sensor default data (pinnr, moisture threshold, measurement interval)
PumpDevice pump {5, 8000, false}; // Init. pump default data (pinnr, pump interval, on (true) / off (false) state )
// Timer objects for handling the different time intervals
Timer timerSensor;
Timer timerPump;
Timer blinkTimer;
void blink() {
if (blinkTimer(gcBlinkInterval)) {
blinkTimer.start();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
}
// Returns true if the measured sensor value is above the specified threshold else it returns false
bool checkSensor(SensorDevice& dev, Timer& wait) {
bool result {false};
if (wait(dev.delay_ms)) {
wait.start();
cout << F("Read Sensor Data: ");
result = analogRead(dev.pin) > dev.threshold;
(result) ? cout << F("Soil too dry\n") : cout << F("Soil moist enough\n");
}
return result;
}
void enablePump(PumpDevice& dev, Timer& wait) {
if (dev.isRunning) { return; } // Return if device is already on
cout << F("Start pump\n");
digitalWrite(dev.pin, HIGH);
dev.isRunning = true;
wait.start();
}
void disablePump(PumpDevice& dev, Timer& wait) {
if (!wait(dev.delay_ms)) { return; } // Return if interval has not elapsed
cout << F("Pump interval over. Stop pump\n");
digitalWrite(dev.pin, LOW);
dev.isRunning = false;
}
void setup() {
Serial.begin(115200);
cout << F("Start...\n");
cout << F("Wait ") << sensor.delay_ms << F(" milliseconds until the first sensor measurement.\n");
pinMode(pump.pin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
blink(); // Does nothing in particular except flash away
// if checksensor returns true, enable the pump
if (checkSensor(sensor, timerSensor)) { enablePump(pump, timerPump); }
// When the pump is on, Switch off the pump when the specified pumping time interval has elapsed.
if (pump.isRunning) { disablePump(pump, timerPump); }
}
Poti simuliert Feuchtemesser
Startwert 270. Grenzwert 500.
Verschieben ändert den Wert.
LED simuliert Pumpe