Hi, I have a problem to include these 3 functions in my home alarm project.
1 View your printouts on both the blynk app and the 16x2 ic2 display
2 View the status of the LED also on the app
3 Activate / Deactivate the alarm.
This is the sketch:
#include <SPI.h>
#include <RFID.h>
#include <EEPROM.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
char auth[] = "lEyJb9wjak_yaAuZBKNv_GlbPA5PvElM";
#define SS_PIN 9
#define RST_PIN 8
#define W5100_CS 10
#define SDCARD_CS 4
// ***IMPORTANTE*** Inserire il codice della propria chiave master.
#define masnum0 170
#define masnum1 222
#define masnum2 159
#define masnum3 26
#define masnum4 241
#define ledPin 3
#define sensorePir1 6 // Ingresso sensore 1
#define releSirena 7 // Contatto pulito a cui collegare una sirena esterna autoalimentata
#define ledRosso 3 // E' il led che indica lo stato della centrale
#define ledGiallo 4 // E' il led che indica lo stato del sensore 1
#define resetKey 5 // pulsante di reset e visualizzazione memoria di allarme
#define dispositivo1 14 // Uscita relè dispositivo 1
RFID rfid(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27,16,2);
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xAD, 0x54 }; // mac address della ethernet shield
byte ip[] = { 192 ,168 ,1 ,100 }; // indirizzo ip statico locale da assegnare ad arduino
byte gateway[] = { 192 ,168 ,1 ,1 }; // indirizzo ip del router
byte subnet[] = { 255 ,255 ,255 ,0 }; // subnet di default
EthernetServer server(80); // porta da aprire sul router per la comunicazione remota
String readString = String(30);
boolean statoAntifurto = 0; // Variabile antifurto attivo
boolean statoAllarme = 0; // Variabile centrale in allarme
boolean statoSirena = 0; // Variabile di stato del relè sirena
boolean statoPir1 = 0; // Variabile di stato del sensore 1
boolean statoDispositivo1 = 0; // Variabile di stato on/off del relè dispositivo 1
boolean cardMaster = 0; // Variabile modalitĂ chiave master
boolean memoriaAllarme = 0; // Variabile per gestire la memoria di allarme
boolean tastoPremuto = 0; // Variabile che controlla la pressione prolungata del tasto reset
int slave; // Contatore di chiavi salvate
int zona = 0; // Variabile che memorizza la zona che ha innescato l'allarme
int timerIngUsc = 0; // Variabile utilizzata per scandire i secondi trascorsi durante i tempi di ingresso o uscita
int faseIngUsc = 0; // Variabile che memorizza se si è nella fase di ingresso (1) o uscita (2)
unsigned long previousMillisSirena = 0; // Variabile utilizzata per gestire i millisecondi del tempo di suono della sirena.
unsigned long currentMillisSirena;
unsigned long previousMillisTempi = 0; // Variabile utilizzata per gestire i millisecondi del tempo di ingresso/uscita.
unsigned long currentMillisTempi;
int sernum0;
int sernum1;
int sernum2;
int sernum3;
int sernum4;
int valPin;
void setup()
{
lcd.init();
SPI.begin();
rfid.init();Ethernet.begin(mac, ip, gateway, subnet);
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(SDCARD_CS, OUTPUT);
pinMode(ledRosso, OUTPUT);
pinMode(releSirena, OUTPUT);
pinMode(ledGiallo, OUTPUT);
pinMode(sensorePir1,INPUT);
pinMode(resetKey, INPUT);
pinMode(dispositivo1, OUTPUT);
digitalWrite(SDCARD_CS, HIGH);
digitalWrite(ledRosso, LOW);
digitalWrite(ledGiallo, LOW);
digitalWrite(releSirena, HIGH);
digitalWrite(dispositivo1, HIGH);
standby();
Blynk.begin(auth);
}
void loop() {
Blynk.run();
// Inizio blocco per la gestione locale della centrale
// Rileva un tag...
if (rfid.isCard()) {
// Legge il seriale...
if (rfid.readCardSerial()) {
sernum0 = rfid.serNum[0];
sernum1 = rfid.serNum[1];
sernum2 = rfid.serNum[2];
sernum3 = rfid.serNum[3];
sernum4 = rfid.serNum[4];
slave = EEPROM.read(0);
// Se il seriale letto corrisponde con il seriale Master
// attiva o disattiva la modalita Memorizzazione chiavi
// e in piĂą visualizza il numero di chiavi salvate...
if (sernum0 == masnum0
&& sernum1 == masnum1
&& sernum2 == masnum2
&& sernum3 == masnum3
&& sernum4 == masnum4) {
if (statoAntifurto == 0) {
lcd.backlight();
if (cardMaster==0) {
lcd.clear();
lcd.print("CARD MASTER");
delay(2000);
lcd.clear();
lcd.print("GESTIONE CHIAVI");
cardMaster = 1;
lcd.setCursor(0, 1);
lcd.print("Chiavi slave: ");
lcd.setCursor(15, 1);
lcd.print(slave);
delay(3000);
}
else {
cardMaster = 0;
lcd.setCursor(0, 1);
lcd.print("Annullata ");
delay(3000);
standby();
}
}
}
// Se invece il seriale letto corrisponde con uno dei tre gruppi
// di chiavi memorizzate allora attiva o disattiva l'antifurto.
else if ((sernum0 == EEPROM.read(1) && sernum1 == EEPROM.read(2) && sernum2 == EEPROM.read(3) && sernum3 == EEPROM.read(4) && sernum4 == EEPROM.read(5))
|| (sernum0 == EEPROM.read(6) && sernum1 == EEPROM.read(7) && sernum2 == EEPROM.read(8) && sernum3 == EEPROM.read(9) && sernum4 == EEPROM.read(10))
|| (sernum0 == EEPROM.read(11) && sernum1 == EEPROM.read(12) && sernum2 == EEPROM.read(13) && sernum3 == EEPROM.read(14) && sernum4 == EEPROM.read(15))) {
lcd.backlight();
if (cardMaster==0) {
// Se l'antifurto non è inserito, lo attiva ed aggiorna a 2 la variabile "faseIngUsc",
// indicando che si è nella fase di uscita.
if (statoAntifurto == 0) {
statoAntifurto = 1;
faseIngUsc = 2;
lcd.clear();
lcd.print("CHIAVE VALIDA");
delay(2000);
lcd.clear();
lcd.print(" TEMPO ");
lcd.setCursor(0, 1);
lcd.print(" USCITA ");
}
else {
if (faseIngUsc != 0) {
timerIngUsc = 0;
faseIngUsc = 0;
}
lcd.clear();
lcd.print("CHIAVE VALIDA");
delay(2000);
disattiva();
}
}
}
// Se il seriale letto è diverso dal master e nemmeno presente in memoria,
// e se è attiva la modalita Memorizzazione chiavi, salva il seriale in memoria
// come slave1, slave2 o slave3.
else if (cardMaster == 1 && slave == 0) {
lcd.clear();
lcd.print("Chiave rilevata!");
EEPROM.write(0, 1);
EEPROM.write(1, sernum0);
EEPROM.write(2, sernum1);
EEPROM.write(3, sernum2);
EEPROM.write(4, sernum3);
EEPROM.write(5, sernum4);
cardMaster = 0;
delay(1000);
lcd.setCursor(0, 1);
lcd.print("Slave 1 salvata!");
delay(3000);
standby();
}
else if (cardMaster == 1 && slave == 1) {
lcd.clear();
lcd.print("Chiave rilevata!");
EEPROM.write(0, 2);
EEPROM.write(6, sernum0);
EEPROM.write(7, sernum1);
EEPROM.write(8, sernum2);
EEPROM.write(9, sernum3);
EEPROM.write(10, sernum4);
cardMaster = 0;
delay(1000);
lcd.setCursor(0, 1);
lcd.print("Slave 2 salvata!");
delay(3000);
standby();
}
else if (cardMaster == 1 && slave == 2) {
lcd.clear();
lcd.print("Chiave rilevata!");
EEPROM.write(0, 3);
EEPROM.write(11, sernum0);
EEPROM.write(12, sernum1);
EEPROM.write(13, sernum2);
EEPROM.write(14, sernum3);
EEPROM.write(15, sernum4);
cardMaster = 0;
lcd.setCursor(0, 1);
lcd.print("Slave 3 salvata!");
delay(3000);
standby();
}
}
}
rfid.halt();
// Inizio blocco per la gestione remota della centrale e dei dispositivi
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (readString.length() < 30) {
readString = readString + c;
}
if (c == '\n') {
Serial.print(readString);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
// Con il seguente comando la centrale spegne il relè del dispositivo 1.
if(readString.startsWith("GET /?disp1&stato=0")) {
Serial.print("\n DISP1 OFF \n");
client.print("DISP1OFF");
digitalWrite(dispositivo1, HIGH);
statoDispositivo1=0;
}
// Con il seguente comando la centrale accende il relè del dispositivo 1.
if(readString.startsWith("GET /?disp1&stato=1")) {
Serial.print("\n DISP1 ON \n");
client.print("DISP1ON");
digitalWrite(dispositivo1, LOW);
statoDispositivo1=1;
}
// Con il seguente comando la centrale disattiva l'antifurto.
if(readString.startsWith("GET /?antifurto&stato=0")) {
Serial.print("\n ANTIFURTO OFF \n");
client.print("ANTIOFF");
disattiva();
}
// Con il seguente comando la centrale attiva l'antifurto.
if(readString.startsWith("GET /?antifurto&stato=1")) {
Serial.print("\n ANTIFURTO ON \n");
client.print("ANTION");
attiva();
}
// Con il seguente comando la centrale risponde con lo stato generale dell'antifurto, quindi anche lo stato delle zone.
if(readString.startsWith("GET /?stato=antifurto")) {
Serial.print("\n STATO ANTIFURTO \n");
client.print("Cameretta, ");
client.print(statoPir1);
client.print(", ");
client.print(statoAllarme);
client.print(", ");
client.print(statoAntifurto);
}
// Con il seguente comando la centrale risponde solo con lo stato dei sensori
if(readString.startsWith("GET /?stato=sensori")) {
Serial.print("\n STATO SENSORI \n");
client.print("Cameretta, ");
client.print(statoPir1);
}
// Con il seguente comando la centrale risponde con lo stato generale della centrale e quindi dei dispositivi.
if(readString.startsWith("GET /?stato=centrale")) {
Serial.print("\n STATO CENTRALE \n");
client.print("Luce camera, ");
client.print(statoDispositivo1);
client.print(", ");
client.print("Cameretta, ");
client.print(statoPir1);
client.print(", ");
client.print("Stato Antifurto, ");
client.print(statoAntifurto);
client.print(", ");
client.print("Stato Allarme, ");
client.print(statoAllarme);
}
readString="";
client.stop();
}
}
}
}
// Questa istruzione serve a far capire alla funzione "tempoIngressoUscita" in quale fase ci troviamo.
if ((faseIngUsc == 1) || (faseIngUsc == 2)) {
tempoIngressoUscita(faseIngUsc);
}
// Quando la centrale va in allarme si attiverà il relè della sirena per X secondi, 60 di default.
if (statoSirena == 1) {
attivaSirena();
}
// Se l'infrarosso rileva un movimento accende il led giallo
if (valPin == 1) {
digitalWrite(ledPin, HIGH);
}
if (digitalRead(sensorePir1) == HIGH) {
digitalWrite(ledGiallo, HIGH);
statoPir1=1;
}
else {
digitalWrite(ledPin, LOW);
digitalWrite(ledGiallo, LOW);
statoPir1=0;
}
// l'infrarosso rileva un movimento e l'antifurto e attivo
// e quindi non in allarme, attiva l'allarme, memorizza la zona corrispondente ed aggiorna a 1 la variabile "faseIngUsc",
// indicando che si è nella fase di ingresso.
if (digitalRead(sensorePir1) == HIGH && statoAntifurto == 1 && statoAllarme == 0 && faseIngUsc == 0){
faseIngUsc = 1;
lcd.clear();
lcd.print(" TEMPO ");
lcd.setCursor(0, 1);
lcd.print(" INGRESSO ");
zona = 1;
}
// Se è stata attivata con la card Master la modalità "Memorizzazione chiavi",
// premendo il pulsante di reset si azzera il database
// delle chiavi salvate fino a quel momento.
if (digitalRead(resetKey) == HIGH && cardMaster == 1) {
delay(100);
cardMaster = 0;
for (int i=0; i<16; i++){
EEPROM.write(i, 0);
}
lcd.backlight();
lcd.clear();
lcd.print("Reset chiavi...");
delay(3000);
standby();
}
// Se si preme il tasto reset mentre la centrale e in standby si potrĂ visualizzare l'ultima memoria di allarme
// se si mantiene premuto invece si effettua un reset
if (digitalRead(resetKey) == HIGH && statoAntifurto == 0) {
tastoPremuto=1;
delay(1000);
if (digitalRead(resetKey) == HIGH && statoAntifurto == 0 && tastoPremuto == 1) {
tastoPremuto=0;
EEPROM.write(16, 0);
lcd.backlight();
lcd.clear();
lcd.print("Memoria Allarme:");
lcd.setCursor(0, 1);
lcd.print("Reset");
delay(3000);
standby();
}
else {
tastoPremuto=0;
lcd.backlight();
lcd.clear();
lcd.print("Memoria Allarme:");
lcd.setCursor(0, 1);
if (EEPROM.read(16) > 0) {
lcd.print("Zona ");
lcd.setCursor(5, 1);
lcd.print(EEPROM.read(16));
}
else {
lcd.print("Nessuna Memoria");
}
delay(3000);
standby();
}
}
}
void standby() {
lcd.clear();
lcd.print("Antifurto TEC.");
lcd.setCursor(0, 1);
lcd.print("Progetto Casa");
delay(1000);
lcd.backlight();
}
void allarme() {
statoAllarme = 1;
statoSirena = 1;
if (memoriaAllarme == 0) {
memoriaAllarme = 1;
EEPROM.write(16, zona);
}
lcd.backlight();
lcd.clear();
lcd.print(" ALLARME! ");
delay(1000);
lcd.backlight();
}
void attiva() {
statoAntifurto = 1;
digitalWrite(ledRosso, HIGH);
lcd.backlight();
lcd.clear();
lcd.print(" ANTIFURTO ");
lcd.setCursor(0, 1);
lcd.print(" ATTIVO ");
delay(1000);
lcd.backlight();
}
void disattiva() {
statoAntifurto = 0;
statoAllarme = 0;
memoriaAllarme = 0;
statoSirena = 0;
zona = 0;
digitalWrite(releSirena, HIGH);
digitalWrite(ledRosso, LOW);
lcd.backlight();
lcd.clear();
lcd.print(" ANTIFURTO ");
lcd.setCursor(0, 1);
lcd.print(" DISATTIVO ");
delay(2000);
standby();
}
void attivaSirena() {
currentMillisSirena = millis();
if(currentMillisSirena - previousMillisSirena >= 60000) { // Di default la sirena suonerĂ per 60 secondi (60 x 1000). Modifica con il numero di secondi che desideri.
previousMillisSirena = currentMillisSirena;
if (digitalRead(releSirena) == HIGH){
digitalWrite(releSirena, LOW);
}
else {
digitalWrite(releSirena, HIGH);
statoSirena = 0;
}
}
}
void tempoIngressoUscita(int fase) {
if (timerIngUsc < 10) { // Di default i tempi di ingresso/uscita sono impostati a 10 secondi. Modifica con il numero di secondi che desideri.
currentMillisTempi = millis();
if(currentMillisTempi - previousMillisTempi >= 500) {
previousMillisTempi = currentMillisTempi;
if (digitalRead(ledRosso) == HIGH){
digitalWrite(ledRosso, LOW);
}
else {
timerIngUsc++;
// Se desideri avere un beep sonoro che scandisse i secondi, collega al pin 2 un buzzer
// e de-commenta la riga seguente.
tone(2, 1047, 500);
digitalWrite(ledRosso, HIGH);
}
}
}
else {
// Una volta trascorsi i secondi impostati, se si è nella fase di ingresso fa scattare l'allarme,
// mentre se si è nella fase di uscita attiva l'antifurto.
faseIngUsc = 0;
timerIngUsc = 0;
if (fase == 1) {
allarme();
}
else if (fase == 2) {
attiva();
}
}
}