-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIrrigationSystem.ino
More file actions
165 lines (135 loc) · 3.39 KB
/
Copy pathIrrigationSystem.ino
File metadata and controls
165 lines (135 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include "src/State.hpp"
#include "src/OnDelayTimer.hpp"
#pragma region global vars
const int COUNT = 5;
State state = State::NONE;
State lastState = State::NONE;
OnDelayTimer ton;
const int q_measureEnable = 13;
const int q_pump = 12;
const int q_vlv1 = 2;
const int q_vlv2 = 3;
const int q_vlv3 = 4;
const int q_vlv4 = 5;
const int q_vlv5 = 6;
const int q_vlvs[COUNT] = {q_vlv1, q_vlv2, q_vlv3, q_vlv4, q_vlv5};
const int i_measure1 = 11;
const int i_measure2 = 10;
const int i_measure3 = 9;
const int i_measure4 = 8;
const int i_measure5 = 7;
const int i_measures[COUNT] = {i_measure1, i_measure2, i_measure3, i_measure4, i_measure5};
int irrigationMask[COUNT] = {LOW};
#pragma endregion
#pragma region Arduino functions
void setup()
{
pinMode(q_measureEnable, OUTPUT);
pinMode(q_pump, OUTPUT);
for (int pin : q_vlvs)
pinMode(pin, OUTPUT);
for (int pin : i_measures)
pinMode(pin, INPUT);
// close valves; turn off pump (note: relay closes contact on LOW)
for (int pin : q_vlvs)
digitalWrite(pin, HIGH);
digitalWrite(q_pump, HIGH);
state = State::INIT;
Serial.begin(9600);
}
void loop()
{
// output debug info
if (state != lastState)
{
Serial.println(state);
lastState = state;
}
// state machine
switch (state)
{
// SENSORS ON
case State::INIT:
{ // measuring corrodes the contacts -> only activate when needed
digitalWrite(q_measureEnable, HIGH);
state = State::AWAIT_MEASUREMENT;
break;
}
// DELAY BEFORE TAKING MEASUREMENT
case State::AWAIT_MEASUREMENT:
{
if (ton.IsElapsed(1000))
{
state = State::MEASURING;
ton.Reset();
}
break;
}
// STORE MEASUREMENTS, STOP SENSORS
case State::MEASURING:
{
bool anyDry = false;
for (int i = 0; i < COUNT; i++)
{
// HIGH = too dry; LOW = moisture OK
int sensVal = digitalRead(i_measures[i]);
irrigationMask[i] = sensVal;
if (sensVal == HIGH)
anyDry = true;
}
if (anyDry)
state = State::START_IRRIGATION;
else
state = State::WAITING;
digitalWrite(q_measureEnable, LOW);
break;
}
// PUMP ON, NECESSARY VALVES OPEN
case State::START_IRRIGATION:
{
digitalWrite(q_pump, LOW);
for (int i = 0; i < COUNT; i++)
// open any valve (LOW) whose sensor reports "too dry" (HIGH)
digitalWrite(q_vlvs[i], invert(irrigationMask[i]));
state = State::IRRIGATING;
break;
}
// STOP AFTER PUMPING FOR 5 s
case State::IRRIGATING:
{
if (ton.IsElapsed(5000))
{
digitalWrite(q_pump, HIGH);
for (int pin : q_vlvs)
digitalWrite(pin, HIGH);
state = State::WAITING;
ton.Reset();
}
break;
}
// MEASURE AGAIN AFTER 10 MINUTES (600.000 ms)
case State::WAITING:
{
if (ton.IsElapsed(600000))
{
state = State::INIT;
ton.Reset();
}
break;
}
default:
break;
}
}
#pragma endregion
#pragma region local functions
int invert(int signal)
{
if (signal == HIGH)
return LOW;
else if (signal == LOW)
return HIGH;
else
return -1;
}
#pragma endregion