-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpwrplnt.cpp
231 lines (203 loc) · 5.74 KB
/
cpwrplnt.cpp
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
//cpwrplnt.cpp
#include "cpwrplnt.h"
#include "eepromanything.h"
#include <dht11.h>
dht11 DHT11;
cPwrplnt::cPwrplnt() :
m_doActions(true),
m_minMoisture(20),
m_targetMoisture(80),
m_wateringDuration(10),
m_wateringPause(60),
m_lightIntensity(255),
m_timeSunrise(28000), // 08:00
m_timeSunset(72000) // 20:00
{
// intentionally left blank
}
void cPwrplnt::init(void)
{
// Read settings and states from EEPROM
EEPROM_readAnything(ADDR_ACTIVE, m_doActions);
EEPROM_readAnything(ADDR_MINMOISTURE, m_minMoisture);
EEPROM_readAnything(ADDR_TARGETMOISTURE, m_targetMoisture);
EEPROM_readAnything(ADDR_WATERINGDURATION, m_wateringDuration);
EEPROM_readAnything(ADDR_WATERINGPAUSE, m_wateringPause);
EEPROM_readAnything(ADDR_LIGHTINTENSITY, m_lightIntensity);
EEPROM_readAnything(ADDR_SUNRISETIME, m_timeSunrise);
EEPROM_readAnything(ADDR_SUNSETTIME, m_timeSunset);
EEPROM_readAnything(ADDR_LASTPUMPSTART, m_lastPumpStart);
EEPROM_readAnything(ADDR_LASTPUMPSTOP, m_lastPumpStop);
}
void cPwrplnt::resetEEPROM()
{
time_t tnow = now();
EEPROM_writeAnything(ADDR_LASTPUMPSTOP, tnow);
EEPROM_writeAnything(ADDR_LASTPUMPSTOP, tnow);
}
void cPwrplnt::setActive(bool active)
{
m_doActions = active;
EEPROM_writeAnything(ADDR_ACTIVE, m_doActions);
}
void cPwrplnt::setMinMoisture(byte minMoisture)
{
if(0 <= minMoisture && minMoisture <= 100)
{
m_minMoisture = minMoisture;
EEPROM_writeAnything(ADDR_MINMOISTURE, m_minMoisture);
}
}
void cPwrplnt::setTargetMoisture(byte targetMoisture)
{
if(0 <= targetMoisture && targetMoisture <= 100)
{
m_targetMoisture = targetMoisture;
EEPROM_writeAnything(ADDR_TARGETMOISTURE, m_targetMoisture);
}
}
void cPwrplnt::setWateringDuration(byte sec)
{
m_wateringDuration = sec;
EEPROM_writeAnything(ADDR_WATERINGDURATION, m_wateringDuration);
}
void cPwrplnt::setWateringPause(byte sec)
{
m_wateringPause = sec;
EEPROM_writeAnything(ADDR_WATERINGPAUSE, m_wateringPause);
}
void cPwrplnt::setLightIntensity(byte intensity)
{
m_lightIntensity = intensity;
EEPROM_writeAnything(ADDR_LIGHTINTENSITY, m_lightIntensity);
}
void cPwrplnt::setSunriseTime(time_t t)
{
if(t < SECS_PER_DAY)
{
m_timeSunrise = t;
EEPROM_writeAnything(ADDR_SUNRISETIME, m_timeSunrise);
}
}
void cPwrplnt::setSunsetTime(time_t t)
{
if(t < SECS_PER_DAY)
{
m_timeSunset = t;
EEPROM_writeAnything(ADDR_SUNSETTIME, m_timeSunset);
}
}
void cPwrplnt::performMeasurements(void)
{
Serial.println(" performMeasurements");
unsigned int tmp_meas;
// brightness (%)
tmp_meas = 1023-analogRead(PIN_BRIGHTNESS);
m_brightness = (byte)((tmp_meas*100)/1023);
// air humidity
// air temperature
DHT11.read(PIN_DHT11);
// TODO variable temperature calibration
m_temperature = DHT11.temperature;
m_temperature -= 2; // Hard coded calibration
m_airHumidity = DHT11.humidity;
// soil moisture (%)
tmp_meas = 1023-analogRead(PIN_MOISTURE);
m_moisture = (byte)((tmp_meas*100)/1023);
// tank water level
// TODO implement
m_waterLevelOk = true;
}
void cPwrplnt::performActions(void)
{
if(!m_doActions)
{
Serial.println(" Pwrplnt disabled");
switchLight(false);
switchPump(false);
return;
}
Serial.println(" performActions");
time_t tnow = now();
// switch Lights according to time of day
if(elapsedSecsToday(tnow) > m_timeSunrise
&& elapsedSecsToday(tnow) < m_timeSunset)
{
// Turn on lights
// TODO take currently measured brightness into account
switchLight(true);
Serial.println(" Daytime!");
}
else
{
// Turn the lights off
switchLight(false);
Serial.println(" Nighttime!");
}
// only act with the pump if the level is ok
if(m_waterLevelOk)
{
// Activate pump accordingly to soil moisture
if(m_moisture < m_minMoisture)
{
Serial.print(" too dry!...");
// Only start pump if enough time has passed
// since the last stop
// and pump is off
if(tnow > (m_lastPumpStop + m_wateringPause)
&& false == m_pumpState)
{
switchPump(true);
}
else
{
if(m_pumpState)
{
Serial.println("pump already running");
}
else
{
Serial.println("but pump not allowed to start again yet");
}
}
}
// Stop pump if moisture level is reached or timeout
// and pump is running
if ((m_moisture > m_targetMoisture)
|| (tnow > (m_lastPumpStart + m_wateringDuration))
&& true == m_pumpState)
{
switchPump(false);
}
}
else
{ // not enough water in reservoir
Serial.println(" Reservoir low!");
switchPump(false);
}
}
void cPwrplnt::switchPump(bool state)
{
m_pumpState = state;
// Relay works inverted
digitalWrite(PIN_PUMPRELAIS, !m_pumpState);
if(m_pumpState)
{
Serial.println(" Pump on");
m_lastPumpStart = now();
EEPROM_writeAnything(ADDR_LASTPUMPSTART, m_lastPumpStart);
}
else
{
Serial.println(" Pump off");
m_lastPumpStop = now();
EEPROM_writeAnything(ADDR_LASTPUMPSTOP, m_lastPumpStop);
}
}
void cPwrplnt::switchLight(bool state)
{
m_lightState = state;
// Relais works inverted
digitalWrite(PIN_LIGHTPWM, !m_lightState);
// TODO do PWM analogWrite(PIN_LIGHTPWM, !m_lightState);
}