Sistema de alarma casera utilizando Netduino Plus (proyecto HomeAlarmPlus)

Se trata de un sistema de monitoreo de alarma simple con Netduino Plus y un panel de alarma típico. Esta aplicación podría ser usado en conjunción con los PC5010 Digital Security Controls (DSC) del panel de control del sistema de seguridad PowerSeries y sensores. Probado con. NET Micro Framework 4.2 (QFE1 y qfe2).

El objetivo de este proyecto es utilizar capacidades de Netduino Plus para controlar el sistema de alarma y reportar las actividades de cualquier detector del sensor de movimiento / por correo electrónico (utilizando protocolo simple de transferencia de correo (SMTP)), un servidor web local y Pachube (ahora Cosm).

Advertencia

Este código contiene información relacionada con un típico sistemas de alarma. Por favor, tenga en cuenta que este procedimiento puede anular la garantía. Cualquier sistema de alarma de cualquier tipo puede ser comprometido deliberadamente o puede fallar al operar como se espera por una variedad de razones.

El autor, Gilberto García, no se hace responsable de los fallos del sistema, tales como: instalación inadecuada, el conocimiento criminal, el acceso de intrusos, la falta de energía, falta de baterías reemplazables, el compromiso de Radio Frecuencia (Wireless) los dispositivos, los usuarios del sistema, detectores de humo, de movimiento detectores, dispositivos de alarma (sirenas, campanas, bocina), líneas telefónicas, falta de tiempo, falta de componentes, pruebas insuficientes, la seguridad y los seguros (propiedad o seguro de vida).

 Hardware
  • Netduino Plus
  • Tarjeta Micro SD
  • Adaptador de tarjeta SD
  • 3mm diodo emisor de luz (LED) verde por zona de alarma y detector de movimiento.
  • 330 ohmios para cada LED.
  • Resistencia 5600 ohmios por zona de alarma y detector de movimiento.
  • Schottky diodo por zona de alarma. Schottky diodo debe tener una baja caída de tensión como el SBR10U40CT.
  • Sparkfun ProtoScrewShield (sku: DEV-09729). Otros escudos que trabajarán son: Proto-Screwshield (Wingshield) kit de Adafruit o WingShield Industries.
  • Conexion WiFi  via WiFly Shield o  un adaptador WiFi .  Testado  con Netgear WNCE3001 , IOGEAR GWU627 y adap tadorMIFI de Telefónica.

OPcional

LED verde con soporte)

Conector Panel impermeable (RR-211300-30)

Cable USB 2.0 tipo A macho a un macho (10 pies o más). Se utiliza para acceder al Netduino Plus tabla en el panel de alarma.
200 Vatios / 350 VA UPS (APC System UPS BE350G o similar).
Botón de reset externo Empuje.
Arduino Proto Shield R3. Más espacio para los componentes adicionales. Mouser Electronics y otros.
LCD 16×2  3.3V para Netduino o 5V para Arduino.
Interruptor DPDT (o éste de Mouser Electronics) para la selección de voltaje LCD.

Circuito
El diagrama realizado con la herramienta Fritzing siguiente muestra cómo el Netduino plus, LEDs y las zonas de alarma (o detector de movimiento) están conectados. LCD circuitos de referencia de Szymon Kobalczy.

HomeAlarmPlus connection diagram (basic circuit) Rev-
HomeAlarmPlus connection diagram (basic circuit) RevA
HomeAlarmPlus connection diagram (enhanced circuit) RevG
Zone/Sensor connection

Tenga en cuenta que una o más zonas consisten en lo siguiente:
a) 1 contacto normalmente abierto y 1 contacto NC con fin de línea (EOL) resistencia.
b) Doble circuito de EOL, 1 Contacto normalmente cerrado con 5.6kohm EOL resistencia y diodo Schottky. Esto hará que la protección necesaria para la Netduino o Arduino.
c) Cada zona de tierra debe ser conectado a la ProtoScrewShield GND.
Netduino / ProtoScrewShield Pin
descripción
A0 Zona # 1
Zona A1 # 2
A2 Zona # 3
A3 Zona # 4
Sensor A4 # 1 [Detector de movimiento]
Zona de LED D2 # 1
D3 Zona LED # 2
D4 Zone LED # 3
D5 LED Zona # 4
D6 o D7 Sensor LED # 1 [Detector de movimiento]

Opciones Web Server

 

 

Opciones
descripción
Page / Root
/ open Abrir último archivo en la tarjeta SD.
/ files Lista sdcard en la tarjeta SD.
/ su superusuario. Muestra opciones adicionales.
/ Pachube muestra la actividad Pachube por zona / Datastream.
/ sobre los créditos de aplicación y versión.
/ delete-confirmar ¿Eliminar último archivo en la tarjeta SD [Ventana de confirmación].
/ delete-última Borrar el último archivo en la tarjeta SD [ninguna ventana de confirmación].
/ diagnóstico por ahora, muestra la memoria disponible en Netduino y las fuerzas para despejar el recolector de basura.
Código
Archivo config.ini debe copiarse en el directorio raíz de la tarjeta SD. La finalidad de este fichero es la de personalizar los parámetros en la tarjeta SD y evitar una mínima modificación del código fuente. Archivos CSS (header_style.css y table_style.css) deben ubicarse en WebResources carpeta.

 

microSD directory structure

Config.ini content:

01 ;AlarmByZones - Programmed for Netduino by Gilberto García - 5/9/2012 
02 ;Feel free to customize this file with your own definitions. 
03 ;[NETDUINO_PLUS_HTTP_PORT] HTTP server port. 
04 ;[ALARM_ZONES] should match with ACTIVE_ZONES constant defined in AlarmByZones.cs and Definitions.cs . 
05 ;[SENSORS] should match with MOTION_SENSORS constant defined in AlarmByZones.cs and Definitions.cs . 
06 ;[USE_EMAIL] Activate/Deactivate email option. Y or N arguments expected. 
07 ;[EMAIL_FREQ] Email frequency in minutes when the alarm/sensor is active.  
08 ;       This will define EMAIL_FREQUENCY in ConfigDefault.cs . 
09 ;[STORE_LOG] Saves alarm/sensor log. Y or N arguments expected. 
10 ;[STORE_EXCEPTION] Saves Netduino exceptions. Y or N arguments expected. 
11 ;[USE_PACHUBE] Activate/Deactivate Pachube option. Y or N arguments expected. 
12
13
14
15 [NETDUINO_PLUS_HTTP_PORT] 
16 8080 
17 [ALARM_ZONES] 
18 Zone1=FIRST FLOOR - Living room windows, Dining room windows, Porch (sliding doors), Garage door access. 
19 Zone2=SECOND FLOOR - Master Bedroom and Bathroom Windows. 
20 Zone3=FIRST FLOOR - Master Bedroom windows. 
21 Zone4=SECOND FLOOR - Bedroom 2 and bathroom windows. 
22 [SENSORS] 
23 Sensor1=Main door access 
24 [USE_EMAIL] 
25
26 [EMAIL_FREQ] 
27 10 
28 [STORE_LOG] 
29
30 [STORE_EXCEPTION] 
31
32 [USE_PACHUBE] 
33

 

Architecture of AlarmByZones (main)

Declaration

01 /// <summary> 
02  /// Alarm zones (Analog Input) 
03  /// </summary> 
04  static SecretLabs.NETMF.Hardware.AnalogInput[] Zones = newSecretLabs.NETMF.Hardware.AnalogInput[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
05  /// <summary> 
06  /// Alarm zones LEDs (Digital Output) 
07  /// </summary> 
08  static Microsoft.SPOT.Hardware.OutputPort[] AlarmLeds = newMicrosoft.SPOT.Hardware.OutputPort[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
09  /// <summary> 
10  /// Motion detector sensors (Analog Input) 
11  /// </summary> 
12  static SecretLabs.NETMF.Hardware.AnalogInput[] Sensors = newSecretLabs.NETMF.Hardware.AnalogInput[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
13  /// <summary> 
14  /// Motion detector LEDs (Digital Output) 
15  /// </summary> 
16  static Microsoft.SPOT.Hardware.OutputPort[] MotionLeds = newMicrosoft.SPOT.Hardware.OutputPort[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
17  /// <summary> 
18  /// Gets the total elapsed time measured by the current instance of each alarm zone. 
19  /// </summary> 
20  static System.Diagnostics.Stopwatch[] stopwatchZones = newStopwatch[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
21  /// <summary> 
22  /// Gets the total elapsed time measured by the current instance of each motion detector sensor. 
23  /// </summary> 
24  static System.Diagnostics.Stopwatch[] stopwatchSensors = newStopwatch[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
25  /// <summary> 
26  /// Flag for detected zones when trigger. 
27  /// </summary> 
28  static bool[] detectedZones = newbool[Alarm.User_Definitions.Constants.ACTIVE_ZONES]; 
29  /// <summary> 
30  /// Flag for detected sensors when is trigger. 
31  /// </summary> 
32  static bool[] detectedSensors = newbool[Alarm.User_Definitions.Constants.MOTION_SENSORS]; 
33  /// <summary> 
34  /// Email 
35  /// </summary>    
36  /// <example> SMTPClient.Email("mail.gmx.com", 587, "[email protected]", "[email protected]", "user password");  
37  /// </example> 
38  static SMTPClient.Email email = newSMTPClient.Email(Alarm.UserData.Email.host, Alarm.UserData.Email.port, 
39    Alarm.UserData.Email.From, Alarm.UserData.Email.To, Alarm.UserData.Email.smtpPassword); 
40  /// <summary> 
41  /// SD Card Event Logger 
42  /// </summary> 
43  public static EventLogger SdCardEventLogger = newEventLogger(); 

Delegates 

1 /// <summary> 
2 /// Monitor zones delegate 
3 /// </summary> 
4 public delegate void MonitorZonesDelegate(); 
5 /// <summary> 
6 /// Monitor motion sensor delegate 
7 /// </summary> 
8 public delegate void MonitorMotionSensorDelegate(); 

Main 

01 public static void Main() 
02
03   Zones[0] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A0); 
04   Zones[1] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A1); 
05   Zones[2] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A2); 
06   Zones[3] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A3); 
07   AlarmLeds[0] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D2,false);       
08   AlarmLeds[1] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D3, false); 
09   AlarmLeds[2] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D4, false); 
10   AlarmLeds[3] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D5, false); 
11   Sensors[0] = newSecretLabs.NETMF.Hardware.AnalogInput(SecretLabs.NETMF.Hardware.NetduinoPlus.Pins.GPIO_PIN_A4); 
12   MotionLeds[0] = newMicrosoft.SPOT.Hardware.OutputPort(Pins.GPIO_PIN_D7, false); 
13   MonitorZonesDelegate monitorZones = newMonitorZonesDelegate(MonitorZones); 
14   MonitorMotionSensorDelegate monitorMotion = newMonitorMotionSensorDelegate(MonitorSensors); 
15   //based on a post by Valkyrie-MT 
17   Console.DEBUG_ACTIVITY("Setting NTP-time"); 
18   SetTime(); 
19   SdCardEventLogger.parseConfigFileContents(Alarm.User_Definitions.Constants.ALARM_CONFIG_FILE_PATH); 
20   InitArrays(); 
21   Console.DEBUG_ACTIVITY(Microsoft.SPOT.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].IPAddress); 
22   SdCardEventLogger.SDCardAccess(); 
23   new Thread(Alarm.ProtoScrewShield_LED.Blink).Start();       
24   new Thread(Alarm.WebServer.startHttp).Start(); 
25   if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
26   
27     Pachube.PachubeLibrary.InitPachubleLibrary(SdCardEventLogger.IsSDCardAvailable(), Alarm.ConfigDefault.Data.STORE_EXCEPTION); 
28     new Thread(Pachube.PachubeLibrary.PachubeConnect).Start(); 
29   
30   while (true
31   
32     Debug.Print("Memory available: " + Debug.GC(true)); 
33     monitorZones(); 
34     monitorMotion(); 
35     Thread.Sleep(Alarm.Common.Alarm_Constants.ALARM_DELAY_TIME); 
36   
37

Main Methods 

001 /// <summary> 
002 /// Loops thru each alarm zone 
003 /// </summary> 
004 static void MonitorZones() 
005
006   for (int i = 0; i < Zones.Length; i++) 
007   
008     int vInput = Zones[i].Read(); 
009     float volts = ((float)vInput / 1024.0f) * 3.3f; 
010     string strZoneDescription = "N/A"//If zone description is not found on SD Card N/A is default description. 
011     Console.DEBUG_ACTIVITY("Zone " + (i + 1).ToString() + ": Volts: " + volts); 
012     //format:                //Zone number, voltage 
013     Pachube.PachubeLibrary.statusToPachube = i == 0 ? (i + 1).ToString() + "," + volts : (i + 1).ToString() + "," + volts +"\r\n" + Pachube.PachubeLibrary.statusToPachube; 
014     AlarmLeds[i].Write(volts >= 3); 
015     //elapsed seconds 
016     double eSeconds = stopwatchZones[i].ElapsedSeconds; 
017     //elapsed minutes 
018     double eMinutes = stopwatchZones[i].ElapsedMinutes; 
019     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eSeconds.ToString() + " seconds"); 
020     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eMinutes.ToString() + " minutes\n"); 
021     if (volts >= 3 ) 
022     
023       /* 
024        Case #1: 
025         !detectedZones[i] = not triggered before. This is the first time in this cycle and first email to send. 
026        Case #2: 
027         detectedZones[i] && eMinutes >= EMAIL_FREQUENCY = triggered before and time is up for sending another email.            
028        */
029       if (!detectedZones[i] || (detectedZones[i] && eMinutes >= Alarm.ConfigDefault.Data.EMAIL_FREQUENCY)) 
030       
031         if (Alarm.Common.Alarm_Info.zoneDescription.Count>0) 
032         
033           if(Alarm.Common.Alarm_Info.zoneDescription.Contains("Zone" + (i + 1).ToString())) 
034           
035             strZoneDescription = (string)Alarm.Common.Alarm_Info.zoneDescription["Zone" + (i + 1).ToString()]; 
036           
037         
038         string info = "Zone " + (i + 1).ToString() + " " + strZoneDescription; 
039         stopwatchZones[i] = Stopwatch.StartNew(); 
040         detectedZones[i] = true
041         email.SendEmail("Alarm Trigger!", info); 
042         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<tr>");
043         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + DateTime.Now.ToString() + "</center></td> ");
044         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center> Zone " + (i + 1).ToString() + "</center></td>");
045         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + strZoneDescription + "</center></td>");
046         Alarm.Common.Alarm_Info.sbActivity.AppendLine("</tr>");             if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
047         
048           //supress timer and update Pachube with new status 
049           Pachube.PachubeLibrary.forceUpdate = true
050         
051         if (SdCardEventLogger.IsSDCardAvailable() && Alarm.ConfigDefault.Data.STORE_LOG) 
052         
053           SdCardEventLogger.saveFile(DateTime.Now.ToString("d_MMM_yyyy--HH_mm_ss") + ".log", info, "Log"); 
054         
055       
056     
057     else
058     
059       detectedZones[i] = false
060     
061   
062
063 /// <summary> 
064 /// Loops thru each sensor 
065 /// </summary> 
066 static void MonitorSensors() 
067 {   
068   for (int i = 0; i < Sensors.Length; i++) 
069   
070     int vInput = Sensors[i].Read(); 
071     float volts = ((float)vInput / 1024.0f) * 3.3f; 
072     string strSensorDescription = "N/A"//If sensor description is not found on SD Card N/A is default description. 
073     Console.DEBUG_ACTIVITY("Sensor " + (i + 1).ToString() + ": Volts: " + volts); 
074     MotionLeds[i].Write(volts >= 3); 
075     double eSeconds = stopwatchSensors[i].ElapsedSeconds; 
076     double eMinutes = stopwatchSensors[i].ElapsedMinutes; 
077     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eSeconds.ToString() + " seconds"); 
078     Console.DEBUG_ACTIVITY("stopwatch[" + i.ToString() + "] = " + eMinutes.ToString() + " minutes\n"); 
079     if (volts >= 3) 
080     
081       /* 
082        Case #1: 
083         !detectedZones[i] = not triggered before. This is the first time in this cycle and first email to send. 
084        Case #2: 
085         detectedZones[i] && eMinutes >= EMAIL_FREQUENCY = triggered before and time is up for sending another email.            
086        */
087       if (!detectedSensors[i] || (detectedSensors[i] && eMinutes >= Alarm.ConfigDefault.Data.EMAIL_FREQUENCY)) 
088       
089         if (Alarm.Common.Alarm_Info.sensorDescription.Count > 0) 
090         
091           if(Alarm.Common.Alarm_Info.sensorDescription.Contains("Sensor" + (i + 1).ToString())) 
092           
093             strSensorDescription = (string)Alarm.Common.Alarm_Info.sensorDescription["Sensor" + (i + 1).ToString()]; 
094           
095         
096         string info = "Sensor " + (i + 1).ToString() + " " + strSensorDescription; 
097         stopwatchSensors[i] = Stopwatch.StartNew(); 
098         detectedSensors[i] = true
099         email.SendEmail("Alarm Trigger!", info); 
100         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<tr>");
101         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + DateTime.Now.ToString() + "</center></td> ");
102         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center> Sensor " + (i + 1).ToString() + "</center></td>");
103         Alarm.Common.Alarm_Info.sbActivity.AppendLine("<td><center>" + strSensorDescription + "</center></td>");
104         Alarm.Common.Alarm_Info.sbActivity.AppendLine("</tr>"); 
105         if (Alarm.ConfigDefault.Data.USE_PACHUBE) 
106         
107           //supress timer and update Pachube with new status 
108           Pachube.PachubeLibrary.forceUpdate = true
109         
110         if (SdCardEventLogger.IsSDCardAvailable() && Alarm.ConfigDefault.Data.STORE_LOG) 
111         
112           SdCardEventLogger.saveFile(DateTime.Now.ToString("d_MMM_yyyy--HH_mm_ss") + ".log", info, "Log"); 
113         
114       
115     
116     else
117     
118       detectedSensors[i] = false
119     
120   
121
122 /// <summary> 
123 /// Synchronize Netduino time with NTP Server 
124 /// </summary> 
125 public static void SetTime() 
126
128   Extension.SetFromNetwork(DateTime.Now, new TimeSpan(-5, 0, 0)); 
129
130 /// <summary> 
131 /// Initializes stopwatch and alarms/sensors arrays 
132 /// </summary> 
133 private static void InitArrays() 
134
135   for (int i = 0; i < Alarm.User_Definitions.Constants.ACTIVE_ZONES; i++) 
136   
137     stopwatchZones[i] = Stopwatch.StartNew(); 
138     detectedZones[i] = false
139   
140   for (int i = 0; i < Alarm.User_Definitions.Constants.MOTION_SENSORS; i++) 
141   
142     stopwatchSensors[i] = Stopwatch.StartNew(); 
143     detectedSensors[i] = false
144   
145

 

Cosm, formerly Pachube, Alarm Console

Final Product

LCD and WiFi Internet Adapter
Alarm Panel with Netduino Plus, LCD and WiFi Internet Adapter

 

Comentarios comunidad Netduino

http://forums.netduino.com/index.php?/topic/4202-home-alarm-system-using-netduino-plus-homealarmplus-project/

Repositorio código fuente
https://github.com/ferraripr/HomeAlarmPlus

Video

YouTube video

Fuente Gilberto García

Deja una respuesta