feat: add support for rfid and wired speaker

This commit is contained in:
Guillermo Marcel 2025-04-12 11:28:52 -03:00
parent 13e8f52d6e
commit 24e993b47d
4 changed files with 241 additions and 82 deletions

20
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,20 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:\\Users\\guill\\Documents\\Arduino\\libraries",
"C:/Users/guill/Documents/Arduino/libraries/TimerFreeTone"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "cl.exe",
"intelliSenseMode": "windows-msvc-x64"
}
],
"version": 4
}

View File

@ -0,0 +1,8 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
"version": "0.2.0",
"configurations": [
]
}

View File

@ -1,12 +1,18 @@
#include <IRremote.hpp> #include <IRremote.hpp>
#include <SPI.h>
#include <MFRC522.h>
#include "melody.h" #include "melody.h"
#include "ledindicator.h" #include "ledindicator.h"
#define IR_RECEIVE_PIN 7 #define IR_RECEIVE_PIN 7
#define RST_RFID 9
#define CS_RFID 10
MFRC522 mfrc522(CS_RFID, RST_RFID);
const int DOOR_SENSOR_PIN = 13; const int DOOR_SENSOR_PIN = 4;
@ -19,129 +25,243 @@ const int DOOR_SENSOR_PIN = 13;
int currentDoorState; // current state of door sensor int currentDoorState; // current state of door sensor
int lastDoorState; // previous state of door sensor int lastDoorState; // previous state of door sensor
bool isArmed = true; bool isArmed = true;
bool isFired = false;
bool muted = false; bool muted = false;
bool ledOn = true; bool ledOn = true;
bool silent = true;
long int delta = 0;
void setup() void setup()
{ {
Serial.begin(115200); // // Establish serial communication Serial.begin(115200); // // Establish serial communication
setupLeds(); setupLeds();
// IR Control
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the receiver
//Door Sensor
pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP);
//Card Reader
SPI.begin(); //Iniciamos el Bus SPI
mfrc522.PCD_Init(); // Iniciamos el MFRC522
currentDoorState = digitalRead(DOOR_SENSOR_PIN); // read state currentDoorState = digitalRead(DOOR_SENSOR_PIN); // read state
isArmed = currentDoorState == LOW; isArmed = currentDoorState == LOW;
Serial.println("Alarm is " + String(isArmed ? "Armed" : "Disarmed")); Serial.println("Alarm is " + String(isArmed ? "Armed" : "Disarmed"));
if(useTimerFreeTone){
Serial.println("configure to use timer free tone");
}
showAlarm(false);
pinMode(TONE_PIN, OUTPUT);
updateIndicator();
delta=millis();
} }
int lastCmd; int lastCmd;
unsigned long lastTime; unsigned long lastTime;
void showAlarm(bool fired) void updateIndicator()
{ {
if(!ledOn) if(!ledOn)
{ {
offLed(); offLed();
return; return;
} }
if(fired) if(isFired)
{ {
if(isArmed) showRed();
{ return;
showRed(); }
}else{ if(currentDoorState==HIGH)
showYellow(); {
} showYellow();
return; return;
} }
if(isArmed) if(isArmed)
{ {
showBlue(); showBlue();
}else{ return;
showGreen();
} }
showGreen();
} }
void loop() { void loop() {
// IrReceiver.stopTimer();
handleCard();
// IrReceiver.restartTimer();
handleDoor(); handleDoor();
handleIR(); handleIR();
handleFire();
} }
void handleIR(){
if (IrReceiver.decode()) {
if(IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)
{
IrReceiver.resume();
return;
}
switch(IrReceiver.decodedIRData.command)
{
case 67:
Serial.println("Play");
isArmed=!isArmed;
showAlarm(false);
Serial.println("Alarm is " + String(isArmed ? "Armed" : "Disarmed"));
// playTone();
break;
case 70:
Serial.println("Led on/off");
ledOn=!ledOn;
showAlarm(false);
break;
default:
Serial.print("unk: ");
Serial.println(IrReceiver.decodedIRData.command);
}
//IrReceiver.printIRResultShort(&Serial); // Print complete received data in one line byte ActualUID[4]; //almacenará el código del Tag leído
// lastTime = millis(); byte Usuario1[4]= {0x23, 0x14, 0x1F, 0x2D} ; //código del usuario 1
// lastCmd=IrReceiver.decodedIRData.command; byte Usuario2[7]= {0x04, 0x38, 0x76, 0x8A, 0x2C, 0x6A, 0x80} ; //código del usuario 2
//Serial.println(IrReceiver.decodedIRData.command); void handleCard(){
IrReceiver.resume(); // Revisamos si hay nuevas tarjetas presentes
if ( !mfrc522.PICC_IsNewCardPresent())
{
return;
} }
if(millis() < delta +2000){
Serial.print(".");
return;
}
delta=millis();
//Seleccionamos una tarjeta
if (! mfrc522.PICC_ReadCardSerial())
{
Serial.println("not readable");
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
showErrorReader();
return;
}
// Enviamos serialemente su UID
Serial.print(F("Card UID:"));
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
ActualUID[i]=mfrc522.uid.uidByte[i];
}
Serial.print(" ");
//comparamos los UID para determinar si es uno de nuestros usuarios
if(!grantAccess()){
Serial.println("Acceso denegado...");
showErrorReader();
return;
}
Serial.println("Acceso concedido!");
isArmed=false;
isFired=false;
updateIndicator();
// Serial.println("Alarm is " + String(isArmed ? "Armed" : "Disarmed"));
// Terminamos la lectura de la tarjeta tarjeta actual
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
bool grantAccess(){
if(compareArray(ActualUID,Usuario1)){
return true;
}else if(compareArray(ActualUID,Usuario2)){
return true;
}
return false;
}
//Función para comparar dos vectores
bool compareArray(byte array1[],byte array2[])
{
if(array1[0] != array2[0])return(false);
if(array1[1] != array2[1])return(false);
if(array1[2] != array2[2])return(false);
if(array1[3] != array2[3])return(false);
return(true);
}
void handleIR(){
if (!IrReceiver.decode()) return;
if(IrReceiver.decodedIRData.flags & IRDATA_FLAGS_IS_REPEAT)
{
IrReceiver.resume();
return;
}
switch(IrReceiver.decodedIRData.command)
{
case 67:
Serial.println("Play");
isArmed=!isArmed;
updateIndicator();
Serial.println("Alarm is " + String(isArmed ? "Armed" : "Disarmed"));
// playTone();
break;
case 70:
Serial.println("Led on/off");
ledOn=!ledOn;
updateIndicator();
break;
case 9:
silent=!silent;
Serial.println("Silent: "+ String(silent));
break;
case 0:
Serial.println("-");break;
default:
Serial.print("unk: ");
Serial.println(IrReceiver.decodedIRData.command);
}
IrReceiver.resume();
} }
void handleDoor(){ void handleDoor(){
if(isFired) return;
lastDoorState = currentDoorState; // save the last state lastDoorState = currentDoorState; // save the last state
currentDoorState = digitalRead(DOOR_SENSOR_PIN); // read new state currentDoorState = digitalRead(DOOR_SENSOR_PIN); // read new state
// state change: LOW -> HIGH // state change: LOW -> HIGH
if (lastDoorState == LOW && currentDoorState == HIGH) { if (lastDoorState == LOW && currentDoorState == HIGH) {
Serial.println("The door-opening event is detected"); Serial.println("The door-opening");
if(!isArmed) if(!isArmed)
{ {
Serial.println("Alarm is dissarmed, not fireing"); Serial.println("Alarm is dissarmed, not fireing");
delay(500);
showAlarm(true);
updateIndicator();
return; return;
} }
Serial.println("Alarm is armed, firing"); Serial.println("Alarm is armed, firing");
showAlarm(true); isFired=true;
if(!muted) updateIndicator();
playTone();
} }
else else
if (lastDoorState == HIGH && currentDoorState == LOW) { // state change: HIGH -> LOW if (lastDoorState == HIGH && currentDoorState == LOW) { // state change: HIGH -> LOW
delay(500); delay(500);
Serial.println("The door-closing event is detected"); Serial.println("The door-closing");
isArmed=true; isArmed=true;
showAlarm(false); updateIndicator();
// TODO: turn off alarm, light or send notification ... // TODO: turn off alarm, light or send notification ...
} }
} }
void showErrorReader(){
showRed();
delay(100);
offLed();
delay(100);
showRed();
delay(100);
offLed();
delay(100);
updateIndicator();
}
void handleFire(){
if(muted || !isFired)
return;
IrReceiver.stopTimer();
// playTone();
playAlarm(silent);
IrReceiver.restartTimer();
}

View File

@ -17,37 +17,48 @@ int duration2[] = { 250, 125, 125, 250, 250, 250, 250, 250 };
int melody3[] = { 262, 196}; int melody3[] = { 262, 196};
int duration3[] = { 250, 125}; int duration3[] = { 250, 125};
const bool useTimerFreeTone =true;
#define TONE_PIN 8 #define TONE_PIN 8
void playTone(){ void playTone(){
if(useTimerFreeTone){
for (int thisNote = 0; thisNote < 8; thisNote++) { // Loop through the notes in the array. // digitalWrite(TONE_PIN, HIGH);
TimerFreeTone(TONE_PIN, melody2[thisNote], duration2[thisNote]); // Play thisNote for duration. // delay(2000);
delay(50); // Short delay between notes. // digitalWrite(TONE_PIN, LOW);
} // return;
return; for (int thisNote = 0; thisNote < 8; thisNote++) { // Loop through the notes in the array.
TimerFreeTone(TONE_PIN, melody2[thisNote], duration2[thisNote]); // Play thisNote for duration.
delay(50); // Short delay between notes.
} }
// // iterate over the notes of the melody:
// for (int thisNote = 0; thisNote < 8; thisNote++) {
// // to calculate the note duration, take one second divided by the note type.
// //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
// int noteDuration = 1000 / noteDurations[thisNote];
// tone(TONE_PIN, melody[thisNote], noteDuration);
// // to distinguish the notes, set a minimum time between them.
// // the note's duration + 30% seems to work well:
// int pauseBetweenNotes = noteDuration * 1.30;
// delay(pauseBetweenNotes);
// // stop the tone playing:
// noTone(TONE_PIN);
// }
} }
float sinVal;
int toneVal;
void playSound(bool silent){
int max = 180;
if(silent)
max = 2;
for(int x = 0; x < max ; x++){
//convert angle of sinusoidal to radian measure
sinVal = (sin(x*(3.1412/180)));
//generate sound of different frequencies by sinusoidal value
toneVal = 2000+(int(sinVal*1000));
//Set a frequency for Pin-out 8
tone(TONE_PIN, toneVal, 3);
// TimerFreeTone(TONE_PIN, toneVal, 2, 5);
delay(2);
}
noTone(TONE_PIN);
}
void playAlarm(bool silent){
playSound(silent);
delay(500);
}