The Seeeduino Cloud is used to transmit a laser beam, identify the detected person, and play a scripted dialogue in response to an event.
/* | |
Title: Grove RFID and MP3 module with Seeeduino Cloud (Yun compatible) connected to Cayenne Dashboard | |
Author: ScottC | |
Date: 10th August 2016 | |
Arduino IDE version: 1.6.9 | |
Website: http://arduinobasics.blogspot.com.au/2016/08/arduino-based-security-project-using.html | |
Description: There are two Arduino MCUs involved in this project. | |
The Seeeduino Cloud (Arduino Yun compatible board) is used to transmit a laser beam, identify the detected person, and play a scripted dialogue in response to an event. | |
The other Arduino is responsible for detecting the presence of a person in the room. When a sensor is triggered, it will notify Cayenne, which | |
in turn will notify this Arduino of that event. | |
This Arduino is responsible for identifying the person in question. | |
If the person identifies themselves successfully within 10 seconds, the alarm is deactivated, | |
otherwise an alarm is triggered, and an alert is sent via email/SMS (using the Cayenne service) to notify me of the intrusion. | |
Libraries required: | |
SoftwareSerial.h : This library should already be installed in the latest Arduino IDE | |
CayenneYun.h : is within the Cayenne-Arduino library download file: https://github.com/myDevicesIoT/Cayenne-Arduino-Library | |
Credits: Some of the code used in this sketch was adapted or inspired from code examples at these sites: | |
http://www.cayenne-mydevices.com/docs/#introduction | |
http://www.seeedstudio.com/wiki/Grove_-_Serial_MP3_Player | |
http://www.seeedstudio.com/wiki/Grove_-_125KHz_RFID_Reader | |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */ | |
#include <SoftwareSerial.h> //SoftwareSerial library required for Arduino communication with the Grove RFID reader and the Grove Serial MP3 player | |
#include <CayenneYun.h> //CayenneYun library is required for successful communication between the Seeeduino Cloud and the Cayenne Dashboard | |
char token[] = "INSERT YOUR TOKEN HERE"; //Cayenne authentication token. This should be obtained from the Cayenne Dashboard. | |
SoftwareSerial mp3(2,3); //Grove Serial MP3 Player is connected to Digital Pins 2 and 3 | |
SoftwareSerial rfid(10,11); //Grove 125kHz RFID reader is connected to Digital Pins 10 and 11 (Note: lower pins may not work with this board) | |
//Global Variables | |
int rfidValue = 0; //rfidValue: used to store the value obtained from the RFID tag | |
int vPin6 = 0; //vPin6: is associated with Virtual Pin 6 on the Cayenne Dashboard - activated when a person is detected by the sensors. | |
int vPin7 = 0; //vPin7: is associated with Virtual Pin 7 on the Cayenne Dashboard - activated when the person fails to identify themselves. | |
unsigned long start_Time; //start_Time: is used in various time related events (logs the start time) | |
unsigned long stop_Time; //stop_Time: is used in various time related events (logs the stop time) | |
unsigned long time_Diff = 0; //time_Diff: is used in various time related events (is used to record the time elapsed from start time to stop time) | |
boolean keyMessagePlayed=false; //keyMessagePlayed: helps to prevent a message from replaying repeatedly when a person is detected. | |
boolean waitingForKey = true; //waitingForKey: is used to identify if we are still waiting for a person to present a valid key or not | |
int songNumber = -1; //songNumber is a variable used to hold the song number to play (from the playlist on the SD card on the MP3 player) | |
/*===============================setup()============================================================================================================================= */ | |
void setup(){ | |
delay(2500); //Delay for 2.5 seconds to allow the Grove MP3 player to initialise | |
mp3.begin(9600); //Establish a communication link with the Grove MP3 player | |
rfid.begin(9600); //Establish a communication link with the Grove 125 kHz RFID reader | |
Serial.begin(9600); //Establish a communication link with my computer (via the Serial monitor) - for debugging purposes. | |
Cayenne.begin(token); //Establish a communication link with the Cayenne Server - the token must match that in the Cayenne Dashboard | |
setVolume(28); //Set the volume of the MP3 player to 28 (Range = 0 to 31, whereby 31 is maximum volume) | |
setPlayMode(0x00); //Configure the MP3 player to play the MP3 file ONCE only (per request). | |
} | |
/*===============================loop()============================================================================================================================= */ | |
void loop(){ | |
Cayenne.run(); //Synchronise with the Cayenne Server | |
if(vPin6&&!vPin7){ //Only progress if Virtual Pin 6 (Person detection) is ACTIVATED but ONLY when Virtual Pin 7 (Intruder alert) has NOT already been activated. | |
if(!keyMessagePlayed){ //This ensures that the message is played only ONCE when a person has been detected. | |
playSong(1); //Play the following message on the Grove MP3 player: "Place your keys on the mat" | |
keyMessagePlayed=true; //keyMessagePlayed is changed to TRUE once the message has been played. | |
} | |
/*This section requests the Arduino to look out for the person's keys, and returns TRUE when a successful identification is made. | |
* It returns FALSE if the person fails to put their keys on the Mat within 10 seconds , OR if the person cannot be identified by the Arduino (e.g. Wrong code) | |
* If a person has been successfully identified/verified, it will play a welcome message, and switch off the "Person Detection Trigger", which will then | |
* be used as a method to switch off the Security scanning process. | |
* If a person fails to be identified within 10 seconds, the person is notified that they have been detected, and an Alarm will sound. | |
* Virtual Pin 7 (Intruder Alert) will be ACTIVATED - which will be used as a Trigger within Cayenne to notify me of an Intruder (via Email or SMS). | |
*/ | |
if(listenForKeys()){ | |
//TRUE = Person Identified within 10 seconds | |
playSong(songNumber); //Play message "Welcome Home - Scott" | |
vPin6 = 0; //Deactivate the "Person Detection" virtual pin (6). | |
keyMessagePlayed=false; //Reset the keyMessagePlayed variable for future detections. | |
} else { | |
//FALSE = Person not identified within 10 seconds | |
playSong(2); //Play message on Grove MP3 player : "Your presence has been detected" | |
delay(4000); //A FOUR second delay is required to allow the message to play, before the alarm sounds. | |
playSong(3); //Sound the ALARM by playing song 2 on the Grove MP3 player. Song numbers are determined by the order they have been written to the SD card. | |
delay(8000); //An EIGHT second delay allows the alarm to sound for 8 seconds. | |
playSong(99); //Playing a non-existing track essentially STOPS the MP3 player. | |
vPin7=1; //ACTIVATE Virtual Pin 7 - Intruder Detected | |
keyMessagePlayed=false; //Reset the keyMessagePlayed variable for future detections. | |
} | |
upDateCayenne(); //Update the Cayenne Dashboard with any changes made to the virtual pins (6 or 7). This method can be found below. | |
} | |
} | |
/*=writeToMP3 function====================================================================================================================================================== | |
* is used to simplify the process of sending commands to the Grove MP3 player | |
*/ | |
void writeToMP3(byte MsgLEN, byte A, byte B, byte C, byte D, byte E, byte F){ | |
byte codeMsg[] = {MsgLEN, A,B,C,D,E,F}; | |
mp3.write(0x7E); //Start Code for every command = 0x7E | |
for(byte i = 0; i<MsgLEN+1; i++){ | |
mp3.write(codeMsg[i]); //Send the rest of the command to the GROVE MP3 player | |
} | |
} | |
/*=setVolume function====================================================================================================================================================== | |
* is used to simplify the process of setting the Volume on the Grove MP3 player | |
* Volume range = 00 (muted) to 31 (max volume) | |
*/ | |
void setVolume(byte Volume){ | |
byte tempVol = constrain(Volume, 0, 31); //Ensure the Volume does not extend beyond the MP3 player's limits | |
writeToMP3(0x03, 0xA7, tempVol, 0x7E, 0x00, 0x00, 0x00); | |
} | |
/*=setPlayMode function====================================================================================================================================================== | |
* is used to simplify the process of setting up the play Mode on the Grove MP3 player | |
* playMode options: | |
* 0x00 = Single song - played only once ie. not repeated. (default) | |
* 0x01 = Single song - cycled ie. repeats over and over. | |
* 0x02 = All songs - cycled | |
* 0x03 = play songs randomly | |
*/ | |
void setPlayMode(byte playMode){ | |
writeToMP3(0x03, 0xA9, playMode, 0x7E, 0x00, 0x00, 0x00); | |
} | |
/*=playSong function====================================================================================================================================================== | |
* is used to simplify the process of playing a specific track on the SD card of the Grove MP3 player. | |
* The track number is determined by the order in which the songs were written to the SD card. | |
* Best to name the tracks in sequence, e.g. 0000_Song0.mp3 , 0001_Song1.mp3 etc etc. | |
* And also best to copy them one by one to the SD card from Song 0 to Song x. | |
*/ | |
void playSong(byte songNum){ | |
writeToMP3(0x04, 0xA0, 0x00, songNum, 0x7E, 0x00, 0x00); | |
} | |
/*=listenForKeys function====================================================================================================================================================== | |
* is used to identify the person detected. | |
* The Arduino will wait a maximum of 10 seconds for the person to place their RFID tag near the Grove RFID reader antenna. | |
* This example shows two RFID tag values that will be accepted. | |
* This method also prints the RFID tag value to the Serial monitor - for debugging purposes. | |
*/ | |
boolean listenForKeys(){ | |
//reset some variables every time this function is called. | |
songNumber = -1; | |
start_Time = millis(); | |
time_Diff = 0; | |
waitingForKey = true; | |
rfidValue=0; | |
//Wait for a valid RFID tag for a maximum of 10 seconds | |
while(time_Diff<10000 && waitingForKey){ | |
Cayenne.run(); //Make sure to stay in contact with the Cayenne Server while waiting for the RFID tag. | |
stop_Time = millis(); | |
time_Diff = stop_Time - start_Time; //Measure the time elapsed. | |
//If an RFID tag is detected by the Grove RFID reader, it will transmit a series of numbers related to the Tag ID. | |
if(rfid.available()){ | |
while(rfid.available()){ //Make sure to read all of the numbers transmitted by the Grove RFID reader | |
rfidValue += rfid.read(); //You could employ a method to extract the exact RFID Tag ID - however just adding each number received - produced a unique number that I could use to identify the person. | |
delay(1); //A small delay between reads - ensures you get all of the numbers from the RFID reader in one go. | |
} | |
Serial.println("RFID VALUE:"); | |
Serial.println(rfidValue); //Print the Unique RFID Tag value to the Serial monitor - useful for debugging | |
//If a person has an RFID tag that can be identified in this list, then play a personalised message for that person. | |
switch(rfidValue){ | |
case 628: //Person #1 has a Tag that generates an rfidValue of 628. | |
songNumber=4; //File#4 (or message number 4) on the Grove MP3 player will be played when this person is detected. | |
waitingForKey = false; //setting the "waitingForKey" variable to FALSE - will allow us to break out of the while loop (instead of waiting for a full 10 seconds). | |
break; | |
case 651: //Person #2 has a Tag that generates an rfidValue of 651. | |
songNumber=5; //File#5 (or message number 5) on the Grove MP3 player will be played when this person is detected. | |
waitingForKey = false; //setting the "waitingForKey" variable to FALSE - will allow us to break out of the while loop (instead of waiting for a full 10 seconds). | |
break; | |
case 694: //Person #3 has a Tag that generates an rfidValue of 694. | |
songNumber=6; //File#6 (or message number 6) on the Grove MP3 player will be played when this person is detected. | |
waitingForKey = false; //setting the "waitingForKey" variable to FALSE - will allow us to break out of the while loop (instead of waiting for a full 10 seconds). | |
break; | |
case 658: //Person #4 has a Tag that generates an rfidValue of 658. | |
songNumber=7; //File#7 (or message number 7) on the Grove MP3 player will be played when this person is detected. | |
waitingForKey = false; //setting the "waitingForKey" variable to FALSE - will allow us to break out of the while loop (instead of waiting for a full 10 seconds). | |
break; | |
case 677: //Person #5 has a Tag that generates an rfidValue of 677. | |
songNumber=8; //File#8 (or message number 8) on the Grove MP3 player will be played when this person is detected. | |
waitingForKey = false; //setting the "waitingForKey" variable to FALSE - will allow us to break out of the while loop (instead of waiting for a full 10 seconds). | |
break; | |
default: | |
waitingForKey = true; //If a person has not been identified, keep waiting for the key/tag until the times runs out. | |
break; | |
} | |
} | |
} | |
/* If we are still waiting for an RFID tag (key) at this point, then we were unsuccessful in identifying the person within 10 seconds. | |
* Returning FALSE - will sound the alarm, and will activate Virtual Pin 7 (Intruder Alert). | |
* Returning TRUE - means that we have identified the person who triggered the sensors, and can therefore relax, and turn OFF the Security sensors. | |
*/ | |
if(waitingForKey){ | |
return false; | |
} else { | |
return true; | |
} | |
} | |
/*=upDateCayenne function====================================================================================================================================================== | |
* This function will transmit the values of vPin6 and vPin7 to the Cayenne Dashboard's Virtual Pin 6 and 7 (respectively). | |
* This will help the Cayenne Server to keep up to date with the status of each variable. | |
*/ | |
void upDateCayenne() { | |
Cayenne.virtualWrite(V6, vPin6); | |
delay(50); | |
Cayenne.virtualWrite(V7, vPin7); | |
delay(50); | |
} | |
/*=CAYENNE_IN(V6) function====================================================================================================================================================== | |
* This will update the Arduino's vPin6 variable to the same value as Virtual Pin 6 on the Cayenne Dashboard. | |
* Which means that you can control the value of vPin6 from the Cayenne app. | |
*/ | |
CAYENNE_IN(V6){ | |
vPin6 = getValue.asInt(); | |
} | |
/*=CAYENNE_IN(V7) function====================================================================================================================================================== | |
* This will update the Arduino's vPin7 variable to the same value as Virtual Pin 7 on the Cayenne Dashboard. | |
* Which means that you can control the value of vPin7 from the Cayenne app. | |
*/ | |
CAYENNE_IN(V7){ | |
vPin7 = getValue.asInt(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment