No os perdais el estupendo trabajo que nos ha enviado Oscar Rodriguez, que se ha construido una pequeña alarma casera utilizando un PIC 16F628, un sensor PIR y un viejo modem. La idea es muy interesante ya que utiliza el sencillo protocolo AT del modem para realizar una llamada telefónica en caso de que el sensor PIR detecte algún movimiento.
No os perdais el video y código fuente a continuación y recordad que podeis enviarnos vuestros proyectos cuando querais a contacto [-at-] bricogeek.com. Estaremos encantados de publicarlos!
Esquema
Código fuente
main.h
#include <16F628A.h> #FUSES NOWDT //No Watch Dog Timer #FUSES INTRC //Internal RC Osc #FUSES NOPUT //No Power Up Timer #FUSES NOPROTECT //Code not protected from reading #FUSES NOBROWNOUT //No brownout reset #FUSES NOMCLR //Master Clear pin used for I/O #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #FUSES NOCPD //No EE protection #use delay(clock=4000000) #use fast_io(b) #use rs232(baud=9600,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8) typedef enum {INICIO, DETECTA, ALARMA, LLAMADO} ESTADOS;
main.c
#include "main.h" ESTADOS estado; volatile int8 dato; // se ha detectado un movimiento y se pasa al estado de alarma #INT_EXT void movimiento() { if(estado == DETECTA) { estado = ALARMA; } } // se ha detectado un carácter en la cola la USART #INT_RDA void lectura() { int8 valor; if(kbhit()) { valor = getc(); if(valor != '\r') { dato = valor; } } } // función genérica que pasa al estado de detección borrando cualquier interrupción anterior y activándola void deteccion() { estado = DETECTA; clear_interrupt(int_ext); enable_interrupts(int_ext); } void main() { setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); setup_timer_1(T1_DISABLED); setup_timer_2(T2_DISABLED,0,1); setup_comparator(NC_NC_NC_NC); setup_vref(FALSE); setup_oscillator(OSC_4MHZ); // Ponemos a todos los pines del puerto B como entrada excepto el de salida de la USART set_tris_b(0xFB); // Empezamos por el estado de inicio estado = INICIO; // La interrupción debe ser cuando pasa de nivel bajo a nivel alto ext_int_edge( L_TO_H ); enable_interrupts(int_rda); enable_interrupts(global); // TODO: USER CODE!! for(;;) { switch(estado) { // En el estado de inicio inicializamos el modem para que no haga eco de los comandos, // los valores de respuesta sean numéricos y apague el altavoz del modem, esperando // 15 segundos para dejar salir al usuario de la sala y pasamos al estado de detección case INICIO: delay_ms(2000); printf("ATE0V0M0\r"); delay_ms(13000); deteccion(); break; // En el estado de detección esperamos la interrupción en modo sleep para consumir menos case DETECTA: sleep(); break; // Se desactiva la interrupción y marcamos el número de teléfono que queramos alertar case ALARMA: disable_interrupts(int_ext); dato = 'A'; printf("ATDTXXXXXXXXX\r"); estado = LLAMADO; break; // Esperamos a que termine la llamada para que vuelva al estado de detección case LLAMADO: if(dato != 'A') { deteccion(); } } } }
Video
Enlace: Alarma casera con PIC