something i forgot to mention, when the same alarm is received, only the time will be updated, because alarms usually come in groups
// alarm receiver by gianmarco
// rev 0.5 20150122 - cleaned up code, added selective alarms and night mode
// rev 0.6 20150123 - added reset display, selective alarms tested
// rev 0.7 20150809 - changed a few details
// rev 0.8 20150915 - changed beeper type, introduced time limits for night mode
// rev 0.81 20151211 - added alarms
//
// add this as reminder
// boolean (8 bit) - simple logical true/false
// byte (8 bit) - unsigned number from 0-255
// char (8 bit) - signed number from -128 to 127. The compiler will attempt to interpret this data type as a character in some circumstances, which may yield unexpected results
// unsigned char (8 bit) - same as ‘byte’; if this is what you’re after, you should use ‘byte’ instead, for reasons of clarity
// word (16 bit) - unsigned number from 0-65535
// unsigned int (16 bit)- the same as ‘word’. Use ‘word’ instead for clarity and brevity
// int (16 bit) - signed number from -32768 to 32767. This is most commonly what you see used for general purpose variables in Arduino example code provided with the IDE
// unsigned long (32 bit) - unsigned number from 0-4,294,967,295. The most common usage of this is to store the result of the millis() function, which returns the number of milliseconds the current code has been running
// long (32 bit) - signed number from -2,147,483,648 to 2,147,483,647
// float (32 bit) - signed number from -3.4028235E38 to 3.4028235E38. Floating point on the Arduino is not native; the compiler has to jump through hoops to make it work. If you can avoid it, you should. We’ll touch on this later.
#include <RFM69.h>
#include <SPI.h>
#include <SPIFlash.h>
#include <Wire.h>
#include <DS3232RTC.h> //http://github.com/JChristensen/DS3232RTC
#include <Streaming.h> //http://arduiniana.org/libraries/streaming/
#include <Time.h> //http://playground.arduino.cc/Code/Time
#include <LiquidCrystal_I2C.h> // i2c lcd display library
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display
#include <SoftwareSerial.h> // software serial library
#include <String.h>
SoftwareSerial mySerial(5,6); // software serial port for GSM module on pin 5 and 6
#define NODEID 1 //unique for each node on same network
#define NETWORKID 99 //the same on all nodes that talk to each other
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "0123456789012345" //exactly the same 16 characters/bytes on all nodes!
//#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 30 // max # of ms to wait for an ack
#define LED 9 // Moteinos have LEDs on D9
#define SERIAL_BAUD 115200
#define NIGHTMODEPIN 14 // pin to set high for night mode
RFM69 radio;
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
void setup() {
lcd.init(); // initialize lcd display
Serial.begin(SERIAL_BAUD);
mySerial.begin(9600); // initialize GSM serial. module was set to 19200, default 9600
delay(10);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
//--------------------------------------------------------------
#ifdef IS_RFM69HW
radio.setHighPower(); //uncomment only for RFM69HW!
#endif
//--------------------------------------------------------------
radio.encrypt(ENCRYPTKEY);
radio.promiscuous(promiscuousMode);
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
Serial.println(buff);
pinMode (NIGHTMODEPIN,INPUT);
pinMode (3, OUTPUT);// enabled sms light
pinMode (2, OUTPUT);// this pin will hardware switch on gsm module pulsating it on HIGH for 1 sec
pinMode (15, INPUT);//pin used to clear display and switch off light
digitalWrite(15, HIGH); //set pin to high by default
delay(1000);
digitalWrite(2,HIGH);
delay(1000);
digitalWrite(2,LOW);
setSyncProvider(RTC.get); // initialize RTC clock
}
// declare most variables here.
// byte ackCount = 0; not used??
word totalarm = 0; // total alarms
char buff1[20];
char buffw[5] = " ";
char buffx[5];
char buff2[20] = " ";
char line1[20] = " ";
char line2[20] = " ";
char line3[20] = " ";
char line4[20] = " ";
char tme[10] = " ";
char tme1[10]= " ";
char tme2[10]= " ";
char tme3[10]= " ";
char tme4[10]= " ";
byte smsen = 0; // flag sms enabled starts at 0 : sms not enabled
void loop() {
if (radio.receiveDone())
{
for (byte i = 0; i < radio.DATALEN+1; i++)
buffx[i] = ((char)radio.DATA[i]);
// send ack to the xmitter
if (radio.ACK_REQUESTED)
{
byte theNodeID = radio.SENDERID;
radio.sendACK();
Serial.println(" - ACK sent.");
}
// decode alarms and stuff
if (strncmp(buffx,"DO01",4) == 0) {
strcpy(buff1,"Door Lab ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"DO02",4) == 0) {
strcpy(buff1,"Door Ktcn ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"DO03",4) == 0) {
strcpy(buff1,"Door Corrid ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"DO04",4) == 0) {
strcpy(buff1,"Door Upstrs ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"DO05",4) == 0)
strcpy(buff1,"Door Wintr2 ");
if (strncmp(buffx,"MO02",4) == 0) {
strcpy(buff1,"Motn Tenne ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO03",4) == 0) {
strcpy(buff1,"Motn Stairs ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO04",4) == 0)
strcpy(buff1,"Motn Living ");
if (strncmp(buffx,"MO05",4) == 0) {
strcpy(buff1,"Motn Upstrs ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO06",4) == 0) {
strcpy(buff1,"Motn Keller ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO07",4) == 0){
strcpy(buff1,"Motn Safe ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO08",4) == 0) {
strcpy(buff1,"Motn Wrkshp ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"MO09",4) == 0) {
strcpy(buff1,"Motn 09 ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"FR01",4) == 0) {
strcpy(buff1,"Fire Worksh ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"FR02",4) == 0) {
strcpy(buff1,"Fire Upstrs ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"FR03",4) == 0) {
strcpy(buff1,"Fire Kitchn ");
if (digitalRead(NIGHTMODEPIN) == HIGH)
soundAlarm();
}
if (strncmp(buffx,"EN01",4) == 0){ // received signal to enable sms sending
strcpy(buff1,"Enable SMS ");
digitalWrite(3,HIGH);//sms enabled
smsen = 1;}
if (strncmp(buffx,"EN00",4) == 0){ // received signal to disable sms sending
strcpy(buff1,"Disable SMS ");
digitalWrite(3,LOW);//sms disabled
smsen = 2;} // set to 2, trick to send sms that sms sending has been disabled
if (smsen > 0 ) { //send sms
mySerial.println("AT+CMGF=1\r"); //Because we want to send the SMS in text mode
delay(500);
mySerial.println("AT+CMGS=\"+41000000000\"");//send sms message, be careful need to add a country code before the cellphone number
delay(500);
mySerial.println(buff1);//the content of the message
delay(500);
mySerial.println((char)26);//the ASCII code of the ctrl+z is 26
mySerial.println();
Serial.println("sms");
delay(500);
if (smsen == 2)
smsen = 0; // now set smsen flag to 0 after having sent the sms signalling the disabling of sms sending
}
sprintf(tme,"%02d:%02d:%02d",hour(),minute(),second());
if (strncmp(buffx,buffw,4) != 0) // if alarms comes from a different sensor, scroll and update display, else only update timestamp
{
strcpy(line4,line3);
strcpy(line3,line2);
strcpy(line2,line1);
strcpy(line1,buff1);
strcpy(tme4,tme3);
strcpy(tme3,tme2);
strcpy(tme2,tme1);
strcpy(tme1,tme);
strcpy(buffw,buffx);
}
else
{
strcpy(line1,buff1);
strcpy(tme1,tme);
}
lcd.backlight(); // when first alarm comes turns on display backlight
// update display writing all 4 lines
lcd.setCursor(0,0);
lcd.print(line4);
lcd.setCursor(12,0);
lcd.print(tme4);
lcd.setCursor(0,1);
lcd.print(line3);
lcd.setCursor(12,1);
lcd.print(tme3);
lcd.setCursor(0,2);
lcd.print(line2);
lcd.setCursor(12,2);
lcd.print(tme2);
lcd.setCursor(0,3);
lcd.print(line1);
lcd.setCursor(12,3);
lcd.print(tme1);
}
// reset display
if (digitalRead(15) == LOW) {
lcd.noBacklight(); // turn off backlight
lcd.clear();// clear display
// clear display variables
memset(line1,0,sizeof(line1));
memset(line2,0,sizeof(line2));
memset(line3,0,sizeof(line3));
memset(line4,0,sizeof(line4));
memset(tme1,0,sizeof(tme1));
memset(tme2,0,sizeof(tme2));
memset(tme3,0,sizeof(tme3));
memset(tme4,0,sizeof(tme4));
memset(buff1,0,sizeof(buff1));
memset(buffx,0,sizeof(buffx));
memset(buffw,0,sizeof(buffw));
}
}
void Blink(byte PIN, int DELAY_MS)
{
pinMode(PIN, OUTPUT);
digitalWrite(PIN,HIGH);
delay(DELAY_MS);
digitalWrite(PIN,LOW);
}
//void soundAlarm() { // this is the function to activate a sound alarm when in night mode
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
// delay(200);
// tone(4,2000,100);
//}
void soundAlarm() { // this is the function to activate a sound alarm when in night mode
if (hour() > 0) {
if(hour() < 7) {
for (int i=0; i <= 9; i++){
digitalWrite(4,HIGH);
delay(100);
digitalWrite(4,LOW);
delay(200);
}
}
}
}