111 lines
2.6 KiB
C++
111 lines
2.6 KiB
C++
#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);
|
|
|
|
pinMode(PUMP_LED_PIN, OUTPUT);
|
|
pinMode(PUMP_PIN, OUTPUT);
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
|
|
// link pots to their config
|
|
for (unsigned int i = 0; i < POT_COUNT; i++) {
|
|
Pot *pot = &pots[i];
|
|
|
|
pot->config = &POT_CONFIGS[i];
|
|
|
|
pinMode(pot->config->valve_pin, OUTPUT);
|
|
pinMode(pot->config->led_pin, OUTPUT);
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
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) {
|
|
int percentage = get_humidity(pot.config->sensor);
|
|
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) {
|
|
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.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(sensorVal, sensor.calibration_wet, sensor.calibration_dry, 100, 0);
|
|
}
|
|
|
|
void set_pump(uint8_t state) {
|
|
digitalWrite(PUMP_LED_PIN, state);
|
|
digitalWrite(PUMP_PIN, state);
|
|
delay(PUMP_DELAY_MS);
|
|
}
|
|
|
|
void set_valve(uint8_t valve, uint8_t state) {
|
|
digitalWrite(valve, state);
|
|
delay(VALVE_DELAY_MS);
|
|
} |