-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparologtato.ino
240 lines (196 loc) · 5.9 KB
/
parologtato.ino
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
232
233
234
235
236
237
238
239
/* Copyright (C) 2009 Nagy Attila Gabor <[email protected]>
*
* This file is part of AHC - AHC Humidity Control.
*
* AHC is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AHC is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AHC. If not, see <http://www.gnu.org/licenses/>.
*
*
* This is the main file of the software. Contains the setup, the
* loop, and the IO controller methods
*/
#include <EtherCard.h>
#include <EEPROM.h>
#include "config.h"
// Output state of the driver
static byte IOState;
// This stores the current working mode of the io
#define IOMODE_AUTO 2
#define IOMODE_ON 1
#define IOMODE_OFF 0
static byte IOMode = IOMODE_OFF;
// Target humidity minimum (below this we will turn on the IO)
static byte targetHumidity_min = DEFAULT_HUMIDITY_MIN;
// Target humidity maximum (turn off the IO above this)
static byte targetHumidity_max = DEFAULT_HUMIDITY_MAX;
// If this is set to 1, then the io mode is always disabled.
static byte manualOff = 0;
// tcp/ip send and receive buffer
byte Ethernet::buffer[880];
/**
* Setup the hardware in and outputs
*/
void setup(void) {
#if DSERIAL
Serial.begin(57600);
Serial.println(F("booting..."));
#endif
pinMode(Control_Pin, OUTPUT);
pinMode(Switch_Pin, INPUT);
// Setup the ethernet card
if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) {
#if !DSERIAL
Serial.begin(57600);
#endif
Serial.println(F("Failed to access Ethernet controller"));
}
ether.staticSetup(myip);
loadSettings();
initHumidity();
#if DSERIAL
ether.printIp(F("IP: "), ether.myip);
ether.printIp(F("GW: "), ether.gwip);
ether.printIp(F("DNS: "), ether.dnsip);
Serial.print(F("Free memory "));
Serial.println(memoryTest(), DEC);
#endif
}
/**
* This is the main loop
*/
void loop(void) {
checkEthernet();
IOController(readManualOffSwitch());
}
/**
* Check the humidity at every five second, a decide wether the
* IO should be turned on or off
* @param boolean force if set to true, then skips the time check
*/
void IOController(boolean force) {
static unsigned long lastMillis = 0;
unsigned long currentMillis = millis();
float humidity;
if (!force && (currentMillis - lastMillis < CHECK_INTERVAL)) return;
lastMillis = currentMillis;
#if DSERIAL
Serial.println(F("Checking IO state"));
#endif
checkDHT();
humidity = getHumidity();
// If the manual off switch is turned on, then
// turn off the io
if (manualOff) {
IOState = 0;
}
// In auto mode update the state depending
// on the current humidity value
else if (IOMode == IOMODE_AUTO) {
if (humidity <= -1000) {
// If there was an error then turn off the IO
IOState = 0;
}
else if (humidity < targetHumidity_min) {
IOState = 1;
}
else if (humidity >= targetHumidity_max) {
IOState = 0;
}
} else {
// In manual mode set to the current value
IOState = IOMode;
}
#if DSERIAL
Serial.print(F("Setting IO to: "));
Serial.println(IOState, DEC);
#endif
digitalWrite(Control_Pin, IOState);
}
/**
* Writes current settings to the EEPROM
*/
void saveSettings() {
int ptr = 0;
byte checksum = 0;
EEPROM.write(ptr++, EEPROM_ID);
EEPROM.write(ptr++, IOMode);
EEPROM.write(ptr++, targetHumidity_min);
EEPROM.write(ptr++, targetHumidity_max);
checksum = IOMode + targetHumidity_min + targetHumidity_max;
EEPROM.write(ptr++, checksum);
}
/**
* Loads the current settings from the EEPROM
*/
void loadSettings() {
int ptr = 0;
byte checksum = 0;
byte i;
if (EEPROM.read(ptr++) != EEPROM_ID) {
#if DSERIAL
Serial.println(F("Invalid EEPROM_ID found"));
#endif
return;
}
// calculate the cheksum
for (i=ptr; i<ptr+3; i++) {
checksum += EEPROM.read(i);
}
if (checksum != EEPROM.read(i)) {
#if DSERIAL
Serial.println(F("Checksum error, when reading from eeprom"));
#endif
return;
}
IOMode = EEPROM.read(ptr++);
targetHumidity_min = EEPROM.read(ptr++);
targetHumidity_max = EEPROM.read(ptr++);
}
/**
* Read the state of the manual off switch, and set it in the
* manualOff global variable
* @return true, if the state has been changed.
*/
boolean readManualOffSwitch() {
static long lastDebounceTime = 0;
static byte lastSwitchState = 0;
byte reading = digitalRead(Switch_Pin);
if (reading != lastSwitchState) {
lastDebounceTime = millis();
}
// save the switch state for the next loop
lastSwitchState = reading;
// Save the switch state, if it's been there for long enought
if (((millis() - lastDebounceTime) > DEBOUNCE_DELAY) && manualOff != reading) {
manualOff = reading;
return true;
}
return false;
}
// this function will return the number of bytes currently free in RAM - for diagnostics only
int memoryTest()
{
int byteCounter = 0; // initialize a counter
byte *byteArray; // create a pointer to a byte array
// More on pointers here: http://en.wikipedia.org/wiki/Pointer#C_pointers
// use the malloc function to repeatedly attempt
// allocating a certain number of bytes to memory
// More on malloc here: http://en.wikipedia.org/wiki/Malloc
while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL )
{
byteCounter++; // if allocation was successful, then up the count for the next try
free(byteArray); // free memory after allocating it
}
free(byteArray); // also free memory after the function finishes
return byteCounter; // send back the highest number of bytes successfully allocated
}