Components and supplies
Arduino Proto Shield
Arduino UNO
Arduino GSM shield V2
Project description
Code
garagedeur_klok_lcd_v12.ino
arduino
1/* 2Pin configuration 3D0 4D1 5D2 GSM 6D3 GSM 7D4 8D5 9D6 10D7 11D8 close door1 12D9 close door2 13D10 14D11 15D12 16D13 17A0 D14 Upper door1 18A1 D15 Lower door1 19A2 D16 Upper door2 20A3 D17 Lower door2 21A4 D18 clock 22A5 D19 clock 23 24*/ 25//Library for LCD 26#include <LiquidCrystal_I2C.h> 27//Library for Clock 28#include <Wire.h> 29#include "RTClib.h" 30//Library for GSM 31#include <SoftwareSerial.h> 32#include <SerialGSM.h> 33 34DS1307 rtc; 35 36SerialGSM cell(2,3); 37 38// initialize the library with the i2c adress and chars and lines 39LiquidCrystal_I2C lcd(0x3F,20,4); 40 41const byte Doors = 2;//number of doors to manage 42const byte Lines = 2;//number of lines on the lcd 43const byte Chars = 16;//number of characters on the lcd 44const long int ClosingTrigger = 60000;//time before an alarm is triggered 45const long int ClosingTime = 20000;//time needed to close the door !!Measure this time for your door!! 46static const uint8_t PinsIn[] = {14,15,16,17};//Array of pins used to minitor the doors 47static const uint8_t PinsOut[] = {8,9};//Array of pins used to control the doors 48char GSMNum[13]="+XXXXXXXXXXX"; // telephone number to send sms 49String ValidAction;//used to check if incomming sms is valid 50String PrevMessage01;//used to move the LCD message one line 51String PrevMessage02;//used to move the LCD message one line 52String PrevMessage03;//used to move the LCD message one line 53byte PrevLine = 1; //previous used line on the LCD 54byte UpperSensor[Doors]; 55byte PrevUpperSensor[Doors]; 56byte LowerSensor[Doors]; 57byte PrevLowerSensor[Doors]; 58char DoorState[Doors];//M=movement, O=open, C=Closed 59byte x=0;//for loop trough number of doors. We start at 0 because list numbering starts at 0 60byte DoorToActivate;//door that has to be activated extracted from SMS 61long int StartMillis[Doors];//remember the starttime of the not closed timer 62bool TimerStarted[Doors];//remember if the not closed timer has been started for a given door 63bool SMSsend[Doors];//remember if a SMS has been send 64 65 66void setup() { 67//start LCD 68lcd.init(); 69lcd.backlight(); 70// Print a message to the LCD. 71lcdmessage("LCD Booted", 1); 72// init clock 73 Wire.begin(); 74 rtc.begin(); 75 76if (! rtc.isrunning()) { 77lcdmessage("RTC is NOT running!", 1); 78// following line sets the RTC to the date & time this sketch was compiled 79 rtc.adjust(DateTime(__DATE__, __TIME__)); 80 } 81 82//loop trough the inputs. 2 inputs for each door 83 for(byte y=0;y<2*Doors;y++) 84 { 85 pinMode(PinsIn[y],INPUT); 86 } 87//loop trough the outputs. 1 output for each door 88//reset timers voor each door 89 for(byte y=0;y<Doors;y++) 90 { 91 pinMode(PinsOut[y],OUTPUT); 92//In order to work with a relay module HIGH is Normal Open 93 digitalWrite(PinsOut[y], HIGH); 94 StartMillis[y]=0; 95 TimerStarted[y]=0; 96 SMSsend[y]=0; 97 } 98Serial.begin(9600); 99 100//setup GSM shield 101cell.begin(9600); 102//for debug cell.Verbose(true); 103lcdmessage("Booting GSM", 1); 104cell.Boot(); 105cell.FwdSMS2Serial(); 106cell.DeleteAllSMS(); 107lcdmessage("GSM Booted", 1); 108} 109 110void loop() { 111 if (x < Doors) 112 { 113//check uppersensors and compare to previous state 114 PrevUpperSensor[x] = UpperSensor[x]; 115 UpperSensor[x] = digitalRead(PinsIn[(2*x)]); 116 if (!(PrevUpperSensor[x] == UpperSensor[x])) 117 { 118 MakeMessage(x, 'U'); 119 } 120//check lowersensors and compare to previous state 121 PrevLowerSensor[x] = LowerSensor[x]; 122 LowerSensor[x] = digitalRead(PinsIn[(2*x)+1]); 123 if (!(PrevLowerSensor[x] == LowerSensor[x])) 124 { 125 MakeMessage(x, 'L'); 126 } 127//Start timer if door not closed else reset timers 128 if (!(DoorState[x] == 'C')) 129 { 130 CheckTimer(x); 131 } 132 else 133 { 134 TimerStarted[x] = 0; 135 StartMillis[x]=0; 136 SMSsend[x]=0; 137 } 138 x= x+1; 139 } 140 else 141 { 142 x=0;//reset doornumber in order to restart the checking cycle 143 } 144//process incomming SMS messages 145 if (cell.ReceiveSMS()) 146 { 147//check if number is valid 148 String SMSSender=cell.Sender(); 149 SMSSender.remove(12); 150 String ValidSender=GSMNum; 151 if (SMSSender == ValidSender) 152 { 153//retrieve DoorToActivate from SMSMessage 154 String SMSMessage=cell.Message(); 155 lcdmessage(SMSMessage, 1); 156 SMSMessage.remove(1); 157 DoorToActivate=SMSMessage.toInt(); 158 159 switch (DoorState[DoorToActivate-1]) 160 { 161 case 'C': 162 ValidAction="Open"; 163 break; 164 165 case 'O': 166 ValidAction="Close"; 167 break; 168 } 169 170 SMSMessage=cell.Message(); 171 SMSMessage.substring(2); 172 if (SMSMessage.substring(2) == ValidAction) 173 { 174 ActivateDoor(DoorToActivate); 175 } 176 else 177 { 178 lcdmessage("No Valid action", 10); 179 } 180//delete all SMS messages 181 cell.DeleteAllSMS(); 182 SMSsend[DoorToActivate-1]=0; 183 } 184 else 185 { 186 lcdmessage("Wrong number", 10); 187 } 188 } 189} 190 191//make message for logging if doorstate has changed. 192void MakeMessage(byte door, char location) 193{ 194 String message = "D"; 195 message.concat(door+1); 196 switch (location) 197 { 198 case 'U': 199 if (PrevUpperSensor[door] < UpperSensor[door]) 200 { 201 message.concat(" = O "); 202 DoorState[door]='O'; 203 } 204 else 205 { 206 message.concat(" > C "); 207 DoorState[door]='M'; 208 } 209 break; 210 211 case 'L': 212 if (PrevLowerSensor[door] < LowerSensor[door]) 213 { 214 message.concat(" = C "); 215 DoorState[door]='C'; 216 } 217 else 218 { 219 message.concat(" > O "); 220 DoorState[door]='M'; 221 } 222 break; 223 } 224 DateTime now = rtc.now(); 225 char buf[100]; 226 strncpy(buf,"hh:mm:ss\\0",100); 227 message.concat(now.format(buf)); 228 lcdmessage(message, 1); 229} 230 231//Check if timer has started for a door and if trigger has been reached, then send SMS 232void CheckTimer(byte door) 233{ 234 if (TimerStarted[door] == 0) 235 { 236 TimerStarted[door]=1; 237 StartMillis[door]=millis(); 238 } 239 else 240 { 241 if ((millis()-StartMillis[door] > ClosingTrigger) && (SMSsend[door] == 0)) 242 { 243 Warning(door); 244// Wait till door normally should be closed 245 delay (ClosingTime); 246 } 247 } 248} 249 250//Creates a message and sends it by SMS 251void Warning(byte door) 252{ 253//create the message 254 char txtMsg[100]; 255 String SMSMessage = "Door "; 256 SMSMessage.concat(door+1); 257 SMSMessage.concat(" is not closed."); 258 SMSMessage.toCharArray(txtMsg,100); 259//send the message 260 sendSMS(GSMNum, txtMsg); 261 SMSsend[door]=1; 262} 263 264//Sends a SMS message to a number 265void sendSMS(char num[13], char msg[100]) 266{ 267 cell.DeleteAllSMS(); 268 cell.Rcpt(num); 269 lcdmessage(msg, 1); 270 cell.Message(msg); 271 cell.SendSMS(); 272} 273 274//Activate a door in order to close or open. Action is always the same. 275//HIGH is normal mode LOW is activated state 276void ActivateDoor(byte door) 277{ 278 Serial.print("Digital out to low : "); 279 Serial.println(PinsOut[door-1]); 280 String Message = "Activate D"; 281 Message.concat(door); 282 lcdmessage(Message, 1); 283 digitalWrite(PinsOut[door-1], LOW); 284 delay(2000); 285 digitalWrite(PinsOut[door-1], HIGH); 286} 287 288//shows a message on the LCD screen 289void lcdmessage(String message, byte visible) 290{ 291 lcd.clear(); 292 lcd.setCursor(0,0); 293 lcd.print(PrevMessage03); 294 lcd.setCursor(0,1); 295 lcd.print(PrevMessage02); 296 lcd.setCursor(0,2); 297 lcd.print(PrevMessage01); 298 lcd.setCursor(0,3); 299 lcd.print(message); 300 PrevMessage03 = PrevMessage02; 301 PrevMessage02 = PrevMessage01; 302 PrevMessage01 = message; 303 delay(visible*1000); 304} 305
Downloadable files
Fritzing scheme
Fritzing scheme
Fritzing scheme
Fritzing scheme
Comments
Only logged in users can leave comments
victormarinus
0 Followers
•0 Projects
Table of contents
Intro
4
0