Skip to content

Commit 44ce87f

Browse files
authored
Create example_8_4.ino
adding in missing file
1 parent 68df7ff commit 44ce87f

File tree

1 file changed

+349
-0
lines changed

1 file changed

+349
-0
lines changed
Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
/*
2+
Example 8-4. The irrigation system sketch
3+
*/
4+
5+
/*
6+
Sketch to accompany the automatic garden irrigation system in
7+
"Getting Started With Arduino, Third Edition". See that book for
8+
the schematic.
9+
10+
http://shop.oreilly.com/product/0636920029267.do
11+
12+
09/04/2014 - Written by Michael Shiloh
13+
12/09/2014 - 1) When displaying on and off times,
14+
must convert back to hours and minutes
15+
2) Humidity threshold was too low
16+
3) Forgot to set digital pins as output
17+
4) new function printSettings() since the same
18+
thing was being done in two different places
19+
20+
This example code is in the public domain.
21+
*/
22+
23+
#include <Wire.h> // Wire library, used by RTC library
24+
#include "RTClib.h" // RTC library
25+
#include "DHT.h" // DHT temperature/humidity sensor library
26+
27+
// Analog pin usage
28+
const int RTC_5V_PIN = A3;
29+
const int RTC_GND_PIN = A2;
30+
31+
// Digital pin usage
32+
const int DHT_PIN = 2; // temperature/humidity sensor
33+
const int WATER_VALVE_0_PIN = 8;
34+
const int WATER_VALVE_1_PIN = 7;
35+
const int WATER_VALVE_2_PIN = 4;
36+
37+
const int NUMBEROFVALVES = 3; // How many valves we have
38+
const int NUMBEROFTIMES = 2; // How many times we have
39+
40+
// Array to store ON and OFF times for each valve
41+
// Store this time as the number of minutes since midnight
42+
// to make calculations easier
43+
int onOffTimes [NUMBEROFVALVES][NUMBEROFTIMES];
44+
int valvePinNumbers[NUMBEROFVALVES];
45+
46+
// Which column is ON time and which is OFF time
47+
const int ONTIME = 0;
48+
const int OFFTIME = 1;
49+
50+
#define DHTTYPE DHT11
51+
DHT dht(DHT_PIN, DHTTYPE); // Create a DHT object
52+
53+
RTC_DS1307 rtc; // Create an RTC object
54+
55+
// Global variables set and used in different functions
56+
DateTime dateTimeNow; // to store results from the RTC
57+
58+
// to store humidity result from the DHT11 sensor
59+
float humidityNow;
60+
61+
void setup(){
62+
63+
// Power and ground to RTC
64+
pinMode(RTC_5V_PIN, OUTPUT);
65+
pinMode(RTC_GND_PIN, OUTPUT);
66+
digitalWrite(RTC_5V_PIN, HIGH);
67+
digitalWrite(RTC_GND_PIN, LOW);
68+
69+
// Initialize the wire library
70+
#ifdef AVR
71+
Wire.begin();
72+
#else
73+
// Shield I2C pins connect to alt I2C bus on Arduino Due
74+
Wire1.begin();
75+
#endif
76+
77+
rtc.begin(); // Initialize the RTC object
78+
dht.begin(); // Initialize the DHT object
79+
Serial.begin(9600); // Initialize the Serial object
80+
81+
// Set the water valve pin numbers into the array
82+
valvePinNumbers[0] = WATER_VALVE_0_PIN;
83+
valvePinNumbers[1] = WATER_VALVE_1_PIN;
84+
valvePinNumbers[2] = WATER_VALVE_2_PIN;
85+
86+
// and set those pins all to outputs
87+
for (int valve = 0; valve < NUMBEROFVALVES; valve++) {
88+
pinMode(valvePinNumbers[valve], OUTPUT);
89+
}
90+
91+
};
92+
93+
void loop() {
94+
95+
// Remind user briefly of possible commands
96+
Serial.print("Type 'P' to print settings or ");$
97+
Serial.println("'S2N13:45' to set valve 2 ON time to 13:34");$
98+
99+
100+
// Get (and print) the current date, time,
101+
// temperature, and humidity
102+
getTimeTempHumidity();
103+
104+
// Check for request from the user
105+
checkUserInteraction();
106+
107+
// Check to see whether it's time to turn any valve ON or OFF
108+
checkTimeControlValves();
109+
110+
// No need to do this too frequently
111+
delay(5000);
112+
}
113+
114+
115+
/*
116+
* Get, and print, the current date, time,
117+
* humidity, and temperature
118+
*/
119+
void getTimeTempHumidity() {
120+
// Get and print the current time
121+
dateTimeNow = rtc.now();
122+
123+
if (! rtc.isrunning()) {
124+
Serial.println("RTC is NOT running!");
125+
// use this to set the RTC to the date and time
126+
// this sketch was compiled
127+
// use this ONCE and then comment it out
128+
// rtc.adjust(DateTime(__DATE__, __TIME__));
129+
return; // if the RTC is not running don't continue
130+
}
131+
132+
Serial.print(dateTimeNow.hour(), DEC);
133+
Serial.print(':');
134+
Serial.print(dateTimeNow.minute(), DEC);
135+
Serial.print(':');
136+
Serial.print(dateTimeNow.second(), DEC);
137+
138+
// Get and print the current temperature and humidity
139+
humidityNow = dht.readHumidity();
140+
// Read temperature as Celsius
141+
float t = dht.readTemperature();
142+
// Read temperature as Fahrenheit
143+
float f = dht.readTemperature(true);
144+
145+
// Check if any reads failed and exit early (to try again).
146+
if (isnan(humidityNow) || isnan(t) || isnan(f)) {
147+
Serial.println("Failed to read from DHT sensor!");
148+
return; // if the DHT is not running don't continue;
149+
}
150+
151+
Serial.print(" Humidity ");
152+
Serial.print(humidityNow);
153+
Serial.print("% ");
154+
Serial.print("Temp ");
155+
Serial.print(t);
156+
Serial.print("C ");
157+
Serial.print(f);
158+
Serial.print("F");
159+
Serial.println();
160+
} // end of getTimeTempHumidity()
161+
162+
163+
/*
164+
* Check for user interaction, which will be in the form of
165+
* something typed on the serial monitor
166+
* If there is anything, make sure it's proper, and perform the
167+
* requested action
168+
*/
169+
void checkUserInteraction() {
170+
// Check for user interaction
171+
while (Serial.available() > 0) {
172+
173+
// The first character tells us what to expect
174+
// for the rest of the line
175+
char temp = Serial.read();
176+
177+
// If the first character is 'P' then
178+
// print the current settings
179+
// and break out of the while() loop
180+
if ( temp == 'P') {
181+
printSettings();
182+
Serial.flush();
183+
break;
184+
} // end of printing current settings
185+
186+
// If first character is 'S' then the rest will be a setting
187+
else if ( temp == 'S') {
188+
expectValveSetting();
189+
}
190+
191+
// Otherwise, it's an error.
192+
// Remind the user what the choices are
193+
// and break out of the while() loop
194+
else
195+
{
196+
printMenu();
197+
Serial.flush();
198+
break;
199+
}
200+
} // end of processing user interaction
201+
}
202+
203+
204+
/*
205+
* Read a string of the form "2N13:45" and separate it
206+
* into the valve number, the letter indicating ON or OFF,
207+
* and the time
208+
*/
209+
void expectValveSetting() {
210+
211+
// The first integer should be the valve number
212+
int valveNumber = Serial.parseInt();
213+
214+
// the next character should be either N or F
215+
char onOff = Serial.read();
216+
217+
// next should come the hour
218+
int desiredHour = Serial.parseInt();
219+
220+
// the next character should be ':'
221+
if (Serial.read() != ':') {
222+
Serial.println("no : found"); // Sanity check
223+
Serial.flush();
224+
return;
225+
}
226+
227+
// next should come the minutes
228+
int desiredMinutes = Serial.parseInt();
229+
230+
// finally expect a newline which is the end of
231+
// the sentence:
232+
if (Serial.read() != '\n') { // Sanity check
233+
Serial.println(
234+
"Make sure to end your request with a Newline");
235+
Serial.flush();
236+
return;
237+
}
238+
239+
// Convert the desired hour and minute time
240+
// to the number of minutes since midnight
241+
int desiredMinutesSinceMidnight
242+
= (desiredHour*60 + desiredMinutes);
243+
244+
// Now that we have all the information set it into the array
245+
// in the correct row and column
246+
247+
if ( onOff == 'N') { // it's an ON time
248+
onOffTimes[valveNumber][ONTIME]
249+
= desiredMinutesSinceMidnight;
250+
}
251+
else if ( onOff == 'F') { // it's an OFF time
252+
onOffTimes[valveNumber][OFFTIME]
253+
= desiredMinutesSinceMidnight;
254+
}
255+
else { // user didn't use N or F
256+
Serial.print("You must use upper case N or F ");
257+
Serial.println("to indicate ON time or OFF time");
258+
Serial.flush();
259+
return;
260+
}
261+
262+
// now print the entire array so user can see what they set
263+
printSettings();
264+
} // end of expectValveSetting()
265+
266+
267+
void checkTimeControlValves() {
268+
269+
// First figure out how many minutes have passed
270+
// since midnight, since we store ON and OFF time
271+
// as the number of minutes since midnight. The
272+
// biggest number will be at 2359 which is
273+
// 23 * 60 + 59 = 1159 which is less than the
274+
// maximum that can be stored in an integer so an
275+
// int is big enough
276+
int nowMinutesSinceMidnight =
277+
(dateTimeNow.hour() * 60) + dateTimeNow.minute();
278+
279+
// Now check the array for each valve
280+
for (int valve = 0; valve < NUMBEROFVALVES; valve++) {
281+
Serial.print("Valve ");
282+
Serial.print(valve);
283+
284+
Serial.print(" is now ");
285+
if ( ( nowMinutesSinceMidnight >=
286+
onOffTimes[valve][ONTIME]) &&
287+
( nowMinutesSinceMidnight <
288+
onOffTimes[valve][OFFTIME]) ) {
289+
290+
// Before we turn a valve on make sure it's not raining
291+
if ( humidityNow > 70 ) {
292+
// It's raining; turn the valve OFF
293+
Serial.print(" OFF ");
294+
digitalWrite(valvePinNumbers[valve], LOW);
295+
}
296+
else {
297+
// No rain and it's time to turn the valve ON
298+
Serial.print(" ON ");
299+
digitalWrite(valvePinNumbers[valve], HIGH);
300+
} // end of checking for rain
301+
} // end of checking for time to turn valve ON
302+
else {
303+
Serial.print(" OFF ");
304+
digitalWrite(valvePinNumbers[valve], LOW);
305+
}
306+
Serial.println();
307+
} // end of looping over each valve
308+
Serial.println();
309+
}
310+
311+
312+
void printMenu() {
313+
Serial.println(
314+
"Please enter P to print the current settings");
315+
Serial.println(
316+
"Please enter S2N13:45 to set valve 2 ON time to 13:34");
317+
}
318+
319+
320+
void printSettings(){
321+
322+
// Print the current on and off settings, converting the
323+
// number of minutes since midnight back to the time
324+
// in hours and minutes
325+
326+
Serial.println();
327+
328+
for (int valve = 0; valve < NUMBEROFVALVES; valve++) {
329+
Serial.print("Valve ");
330+
Serial.print(valve);
331+
Serial.print(" will turn ON at ");
332+
333+
// integer division by 60 gives the hours
334+
// since integer division drops any remainder
335+
Serial.print((onOffTimes[valve][ONTIME])/60);
336+
337+
Serial.print(":");
338+
339+
// the minutes are the remainder after dividing by 60.
340+
// get the remainder with the modulo (%) operator
341+
Serial.print((onOffTimes[valve][ONTIME])%(60));
342+
343+
Serial.print(" and will turn OFF at ");
344+
Serial.print((onOffTimes[valve][OFFTIME])/60); // hours
345+
Serial.print(":");
346+
Serial.print((onOffTimes[valve][OFFTIME])%(60)); // minutes
347+
Serial.println();
348+
}
349+
}

0 commit comments

Comments
 (0)