About the project
Build yourself your own temperature monitoring system with MAXIMUM and MINIMUM temperature thresholds, keep alive massages and (oldies but goldies as) SMS paging and remote ARM/DISARM system. You can supervise one or more 1WIRE temperature sensor(s) and page via SMS the "heating and chilling events" and keep alive messages, including last temperature. You can ENABLE/DISABLE the alarm system from remote via single SMS. This project uses for SMS integration the pin 2 pin compatible dual SIM GSM shield (c-uGSM), nano GSM shield (h-nanoGSM), or 3G shield (d-u3G).
Needed parts
- Arduino UNO
- c-uGSM - dual SIM GSM shield [micro] or
- h-nanoGSM - GSM shield [nano] or
- d-u3G - 3G/UMTS shield [micro]
- 1WIRE temperature sensor(s) - I use DALLAS/MAXIM 18B20
- 2.2kb resistor
- some connecting wires
- Power source(s)
CREDITS
Inside this project we used for 1WIRE temperature the "Dallas Temperature Control Library" developed by Miles Burton & Tim Newsome >> Arduino Library for Dallas Temperature ICs reference here. Thank you guys! Nice job!
About c-uGSM, d-u3G and h-nanoGSM shields
There are pin 2 pin compatible shields, first one it is quad band GSM only(world wide compatible) and has support for 2SIMs and the second one it is SINGLE SIM 3G only (North American version) / 3G+GSM (European and rest of the world version).
Those shields are compact as 1.25"x1.57"(31.75x39.88mm) / 1.35"x1.57"(34.29x39.88mm), weight around 10g, have USB support (communication and powering), auto level 2.8V-5V digital interfaces and Lithium Polimer charger integrated.
The third one - h-nanoGSM - became commercially available in 2016, August. It is a quad band GSM only(world wide compatible) + Bluetooth 3.0 nano shield, packed in an compact format 1.25"x1.16"(31.75x29.46mm) and with weight around 8g. Same as his bigger brothers (c-uGSM and d-u3G), it is not only a break-board, but a full shield having powerful features embedded, as: USB support (communication and powering), auto level 2.8V-5V digital interfaces and Lithium Polimer charger integrated.
DALLAS/MAXIM 18B20 temperature sensor
Solder the 2.2kb resistor between 18B20 Vdd pin(3)and 18B20 DQ pin(2). 18B20 Vdd pin(3) must be wired to Arduino 5V, 18B20 DQ pin(2) to Arduino D4 and 18B20 GND pin(1) to Arduino GND....see details bellow. DALLAS/MAXIM 18B20 reference here.
Hardware connections
In the picture bellow (d-u3G - 3G shield wiring example) you can observe all logical connections.
For c-uGSM/h-nanoGSM shields (GSM only versions) usage: just connect the wires to the very same pins of the GSM shield.
Brief 3G / GSM shield powering wiring:
- "WITHOUT Lithium Polymer configuration" configuration >> connect +4V power supply (g-SPS 4V [DDRV] recomended) to the 3G/GSM shield "Vcc 4V" pin.
- "WITH Lithium Polymer" configuration >> connect +5V power supply (g-SPS 5V [LiPOL] recomended) to the 3G/GSM shield "Vin 5V" pin.
Read the reference: c-uGSM, h-nanoGSM and d-u3G how to start.
The temperature sensor it is connected as following:
18B20 Vdd pin(3) must be wired to Arduino 5V, 18B20 DQ pin(2) to Arduino D4 and 18B20 GND pin(1) to Arduino GND. Do not forget to solder a 2.2kb resistor between 18B20 Vdd pin(3)and 18B20 DQ pin(2).
HINT: if you would like to have multiple 1WIRE temperature sensors, just connect them in paralel mode (single pull up resistor requiered... check for proper value...) and hack the software (use 1,2.. sensorIndex in "sensors.getTempCByIndex(sensorIndex)").
Software
a. We use version Dallas Temperature library 3.7.2 beta. Download from here: Miles Burton Dallas Temperature library v 3.72 beta.
b. Install this library >> how to install here.
c. Start making a folder named "SMS_THERMAL_alarm_supervisor".
d. Then download the
"c-uGSM kickstart for Arduino" from c-uGSM CODE SAMPLES and UTILITIES, or
"h-nanoGSM kickstart for Arduino" from h-nanoGSM CODE SAMPLES and UTILITIES, or
"d-u3G kickstart for Arduino" from d-u3G CODE SAMPLES and UTILITIES if you use the d-u3G shield. Product EMEI and your email adress is requiered in order to perform the download.
c. Uncompress the archive and copy "cuGSM_basic_lbr.h", "cuGSM_basic_lbr.ino", "cuGSM_SMS_lbr.h" and "cuGSM_SMS_lbr.ino" ("du3_basic_lbr.h", "du3G_basic_lbr.ino", "du3G_SMS_lbr.h" and "du3G_SMS_lbr.ino" - 4 d-u3G users, or "hnanoGSM_basic_lbr.h", "hnanoGSM_basic_lbr.ino", "hnanoGSM_SMS_lbr.h" and "hnanoGSM_SMS_lbr.ino" 4 the h-nanoGSM users) files to the folder previously created.
d. Copy the code bellow and make a file called "SMS_THERMAL_alarm_supervisor.ino" in the very same folder as above. Alternate, you can
download from here (right click & save as):
SMS_THERMAL_alarm_supervisor.ino : ARDUINO THERMAL SMS ALARM & GSM/3G SHIELD - main code
SMS_THERMAL_alarm_supervisor.ino
1 | /* |
2 | SMS_THERMAL_alarm_supervisor.ino v 0.3/20160114 - c-uGSM shield v 1.13 /d-u3G shield 1.13 SOFTAWARE EXAMPLE |
3 | COPYRIGHT (c) 2015-2016 Dragos Iosub / R&D Software Solutions srl |
4 | |
5 | You are legaly entitled to use this SOFTWARE ONLY IN CONJUNCTION WITH c-uGSM or d-u3G DEVICES USAGE. Modifications, derivates and redistribution |
6 | of this software must include unmodified this COPYRIGHT NOTICE. You can redistribute this SOFTWARE and/or modify it under the terms |
7 | of this COPYRIGHT NOTICE. Any other usage may be permited only after written notice of Dragos Iosub / R&D Software Solutions srl. |
8 | |
9 | This SOFTWARE is distributed is provide "AS IS" in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
10 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
11 | |
12 | Dragos Iosub, Bucharest 2016. |
13 | http://itbrainpower.net |
14 | */ |
15 | |
16 | |
17 | #define du3GShieldUsage //comment this if you use the c-uGSM shield |
18 | |
19 | static char phoneNumber[15] = "0712345678"; //destination number |
20 | |
21 | static char nunderstand[40] = "? enable cmd: #1, disable cmd: #0."; |
22 | static char armed[10] = "ARMED"; |
23 | static char unarmed[10] = "NOTARMED"; |
24 | static char boot[13] = "BOOT EVENT "; |
25 | |
26 | int keepAlivePeriod = 3600; //send SMS at every keepAlivePeriod seconds |
27 | int samplingPeriod = 15; //interval in seconds between scans... keep it > 15 sec |
28 | int lowTempLevel = 18; //low temperature warning in C grades |
29 | int highTempLevel = 26; //high temperature warning in C grades |
30 | |
31 | #define ONE_WIRE_BUS 4 //Arduino Digital pin used for 1Wire temperature sensor reading |
32 | |
33 | #ifdefined(du3GShieldUsage) //for d-u3G hardware only! |
34 | //#define HARDWARERELEASE 1 //un-comment this only if module SN bw. 031000 032999 and comment the next one |
35 | #define HARDWARERELEASE 2 //default mode! SN > 033000 |
36 | #endif |
37 | /*#####NO PARAMS TO CHANGE BELLOW#####*/ |
38 | int warningStatus = 0; //do not change it! |
39 | |
40 | #include <OneWire.h> |
41 | #include <DallasTemperature.h> |
42 | |
43 | // Setup a oneWire instance to communicate with any OneWire devices |
44 | // (not just Maxim/Dallas temperature ICs) |
45 | OneWire oneWire(ONE_WIRE_BUS); |
46 | |
47 | // Pass our oneWire reference to Dallas Temperature. |
48 | DallasTemperature sensors(&oneWire); |
49 | |
50 | #define powerPIN 7 //Arduino Digital pin used to power up / power down the modem |
51 | #define resetPIN 6 //Arduino Digital pin used to reset the modem |
52 | #define statusPIN 5 //Arduino Digital pin used to monitor if modem is powered |
53 | |
54 | int supervisorMask = 1; //mask temperature monitoring 1 - monitor enabled, 0 - monitor disabled |
55 | |
56 | #if defined (du3GShieldUsage) |
57 | #include "du3G_basic_lbr.h" |
58 | #include "du3G_SMS_lbr.h" |
59 | #else |
60 | #include "cuGSM_basic_lbr.h" |
61 | #include "cuGSM_SMS_lbr.h" |
62 | #endif |
63 | |
64 | #if (ARDUINO >= 100) |
65 | #include "Arduino.h" |
66 | #include <SoftwareSerial.h> |
67 | #else |
68 | #include "WProgram.h" |
69 | #include <NewSoftSerial.h> |
70 | #endif |
71 | |
72 | #define UNO_MODE //used by modem library |
73 | #define BUFFDSIZE 162 //used by modem library |
74 | |
75 | SoftwareSerial agsmSerial(2, 3); //RX==>2 ,TX soft==>3 |
76 | |
77 | char ch; |
78 | char buffd[BUFFDSIZE]; |
79 | char readBuffer[162]; |
80 | //static char mBuffer[162]; |
81 | int state=0, i=0, powerState = 0; |
82 | |
83 | unsigned long startTime = 0; |
84 | unsigned long lastSMSTime = 0; |
85 | float temp = 0; |
86 | |
87 | void procRespose(char* msg){ |
88 | int tempint = (int) temp; |
89 | float afterdot = temp - (float)tempint; |
90 | sprintf(readBuffer, "%s - Temperature is: %i.%i", msg, tempint, (int)(afterdot*100)); |
91 | Serial.println(readBuffer);Serial.flush();delay(150); |
92 | sendSMS(phoneNumber, readBuffer); //confirm command executed |
93 | delay(100); |
94 | } |
95 | |
96 | void setup(){ |
97 | Serial.begin(19200); //start serial connection |
98 | |
99 | pinMode(13, OUTPUT); //configure the UNO D13 as output - UNO embedded LED used as ARMED/DISARMED status indicator |
100 | |
101 | agsmSerial.begin(9600); //next, modem setup |
102 | clearagsmSerial(); |
103 | clearSerial(); |
104 | delay(10); |
105 | |
106 | modemHWSetup(); //configure UNO IN and OUT to be used with modem |
107 | |
108 | Serial.flush(); |
109 | agsmSerial.flush(); |
110 | delay(500); |
111 | |
112 | Serial.println(F("wait until c-uGSM/d-u3G is ready")); |
113 | Serial.flush(); |
114 | |
115 | powerOnModem(); |
116 | |
117 | clearBUFFD(); |
118 | while(strlen(buffd)<1){ |
119 | getIMEI(); |
120 | delay(500); |
121 | } |
122 | |
123 | //Serial.println(F("modem is up. prepare it for SMS processing")); |
124 | //Serial.flush(); |
125 | |
126 | ready4SMS = 0; |
127 | ready4Voice = 0; |
128 | |
129 | //Serial.print(F("modem IMEI: ")); Serial.flush(); |
130 | |
131 | setupMODEMforSMSusage(); |
132 | |
133 | Serial.println(F("modem ready.. let's proceed")); |
134 | Serial.flush(); |
135 | delay(100); |
136 | |
137 | supervisorMask = 1; |
138 | |
139 | sensors.begin(); //1Wire temperature sensor init |
140 | |
141 | startTime = 0; |
142 | lastSMSTime = 0; |
143 | warningStatus = -100; //force BOOT message |
144 | } |
145 | |
146 | |
147 | void loop(){ |
148 | if (millis() - startTime < (unsigned long)samplingPeriod*1000){//waiting period |
149 | //process SMS commands - start |
150 | listSMS(); //find the last used SMS location |
151 | clearagsmSerial(); |
152 | int cnt; |
153 | cnt = noSMS; |
154 | while (cnt>0){ |
155 | readSMS(cnt); //the SMS content will be returned in buffd |
156 | //here process SMS the content - start |
157 | |
158 | Serial.print(F("SMS content: "));Serial.flush();delay(50); |
159 | Serial.println(buffd);Serial.flush();delay(50); |
160 | |
161 | delay(50); |
162 | clearagsmSerial(); |
163 | delay(50); |
164 | |
165 | if(strlen(buffd) > 0){ //non empty SMS |
166 | if(buffd[0] == '#' && buffd[1]== '1'){ //enable send SMS on event detection |
167 | procRespose((char*)armed); |
168 | supervisorMask = 1; |
169 | } |
170 | else { |
171 | if(buffd[0]== '#' && buffd[1]== '0'){ //disable send SMS on event detection |
172 | procRespose((char*)unarmed); |
173 | supervisorMask = 0; |
174 | }else{ //unknown command |
175 | procRespose((char*)nunderstand); |
176 | } |
177 | } |
178 | |
179 | deleteSMS(cnt); //free the SMS location |
180 | } |
181 | //here process SMS the content - end |
182 | clearBUFFD(); |
183 | clearagsmSerial(); |
184 | cnt--; |
185 | } |
186 | //process SMS commands - stop |
187 | digitalWrite(13, supervisorMask); //show ENABLED/DISABLED on Arduino LED |
188 | delay(250); |
189 | } |
190 | else{ |
191 | startTime = millis(); |
192 | |
193 | sensors.requestTemperatures(); |
194 | |
195 | temp = sensors.getTempCByIndex(0); |
196 | |
197 | memset(readBuffer, 0x00, sizeof(readBuffer)); |
198 | int tempint = (int) temp; |
199 | float afterdot = temp - (float)tempint; |
200 | |
201 | int sendSMScondition = 0; |
202 | if (temp < lowTempLevel){ |
203 | if ((warningStatus != -1) || (millis() - lastSMSTime > (unsigned long)keepAlivePeriod/10*1000)){////ALERTS came 10 time faster than keep alive |
204 | sendSMScondition = 1; |
205 | lastSMSTime = millis(); |
206 | if (warningStatus < -1) |
207 | sprintf(readBuffer, boot); |
208 | warningStatus = -1; |
209 | } |
210 | sprintf(readBuffer, "%sLow temperature warning: ", readBuffer); |
211 | } |
212 | else if (temp > highTempLevel){ |
213 | if ((warningStatus != 1) || (millis() - lastSMSTime > (unsigned long)keepAlivePeriod/10*1000)){//ALERTS came 10 time faster than keep alive |
214 | sendSMScondition = 1; |
215 | lastSMSTime = millis(); |
216 | if (warningStatus < -1) |
217 | sprintf(readBuffer, boot); |
218 | warningStatus = 1; |
219 | } |
220 | sprintf(readBuffer, "%sHigh temperature warning: ", readBuffer); |
221 | } |
222 | else{ |
223 | if ((warningStatus != 0) || (millis() - lastSMSTime > (unsigned long)keepAlivePeriod*1000)){ |
224 | sendSMScondition = 1; |
225 | lastSMSTime = millis(); |
226 | if (warningStatus < -1) |
227 | sprintf(readBuffer, boot); |
228 | } |
229 | sprintf(readBuffer, "%sNormal temperature: ", readBuffer); |
230 | warningStatus = 0; |
231 | } |
232 | sprintf(readBuffer, "%s %i.%i", readBuffer, tempint, (int)(afterdot*100)); |
233 | Serial.println(readBuffer); |
234 | Serial.flush(); |
235 | |
236 | delay(150); |
237 | if(sendSMScondition > 0){ |
238 | if(supervisorMask != 0) |
239 | sendSMS(phoneNumber, readBuffer); //send information |
240 | sendSMScondition = 0; |
241 | } |
242 | |
243 | } |
244 | } |
245 |
e. Edit the "SMS_THERMAL_alarm_supervisor.ino" (double click on the file; this one will be open by the ARDUINO environment).
Write in your desired destination mobile number on line 19. (Before this you may check the supported SMS number format by your NMO, using our kickstart software.)
Input the desired values for the temperature thresholds, sampling and keepalive time. You may edit the SMS commands and the SMS messages assigned to the alarm events.
If you use one of the c-uGSM or h-nanoGSM shields: comment line 17.
Behaviour. How to use it.
#0 DISARM the ALARM, #1 ARM the ALARM. Any other received SMS, makes the ALARM to reply with a sort of "help message".
KEEP ALIVE SMS >> the thermal supervisor send an SMS (with STATUS and last temperature) at each "keepAlivePeriod" seconds, if the temperature it is placed inside the "lowTempLevel" and "highTempLevel" threshold interval, or at
at each "keepAlivePeriod/10" seconds, if the temperature it is outside the interval (ALARM STATUS).
Arduino LED (D13) copy the ARM/DISARM status.
Usage areas
...some (crazy) sugestions:
- newborn baby temperature monitoring.... JUST KIDDING GUYS!
- home-brewed beer fermentation barel ;)
- cellar temperature monitoring
- aquariums monitoring
- freezers
- heaters ...others. Anyway, always adapt the temperature sensor(s) to the environment (Eg.: liquids,..) or use proper encapsulated sensors.
TUTORIAL and SOFTWARE ARE PROVIDED WITHOUT ANY WARRANTY!!! USE IT AT YOUR OWN RISK!!!!
Possible improvements
- Restrict SMS processing only from "phoneNumber" (master number)... Just look in the function readSMS (SMS library), after seacond readline(), the buffd variable contains the SMS header (sender number, date+time).. Just processe there in order to extract the SMS sender number...
- Add additional temperature threshold levels, in order control and compensate the temperature drift using one or more PELTIER CELLS via a Arduino digital output plus a TIP122 in open collector configuration or a relay??