IR Beam Hack – Barriera infrarossi

immagine ladro

 

Ho recentemente acquistato due coppie di barriere infrarossi che si trovano facilmente nei negozi online,  la mia scelta è caduta in particolar modo in questo modello alto 55cm e con tre fasci infrarossi (a differenza della foto che ne ha quattro 😛 ) :

 barriera infrarossi

Il problema che ho riscontrato immediatamente è il fatto che l’elettronica di controllo attiva l’allarme solamente se vengono interrotti tutti e tre i fasci infrarossi. Queste barriere sono infatti progettate per essere posizionate in spazi aperti dove bisogna rilevare il passaggio di una persona, evitando falsi allarmi dovuti a piccoli animali.

La mia intenzione invece era l’installazione della barriera infrarossi a filo muro, così da proteggere le parti più sensibili del portoncino d’ingresso quali la maniglia ed il cilindro di chiusura a chiave.

Con una distanza tra i fasci infrarossi di circa 15cm è difficile per un possibile ladro interrompere contemporaneamente tutti e tre i fasci. E’ invece molto più facile interromperne uno o due mentre si cerca di manomettere in qualche modo la serratura.

Dovevo quindi modificare il funzionamento dell’elettronica di controllo permettendo l’avvio dell’allarme dopo l’interruzione di un singolo fascio ovviamente evitando possibili falsi allarmi.

In occasioni del genere bisogna iniziare un bel reverse engineering!

Detto fatto ho aperto e disassemblato entrambe le barre. Ogni coppia è formata da una trasmittente ed una ricevente.

La barra trasmittente è relativamente semplice, comprende un regolatore lineare di tensione LM7809 per abbassare la tensione d’ingresso (12V) a 9V ed un piccolo circuito integrato anonimo usato come oscillatore per pilotare tre coppie di diodi IR:

trasmittente IR

La barra ricevente invece è leggermente più complessa, essa infatti possiede tre fototransistor che ricevono il segnale IR e lo passano ad un microcontrollore (SM894051) che si occupa di attivare un relè ed un buzzer in caso di allarme oltre che avviare una trasmissione radio tramite il modulo radio a 433MHz presente nell’estremità inferiore del PCB. La parte di alimentazione comprende invece un LM7809 per regolare la tensione a 9V ed alcuni regolatori LM7805 per fornire 5V stabili al microcontrollore ed al buzzer:

ricevente IR

La soluzione più semplice in questo caso è rimuovere il microcontrollore originale e sostituirlo con uno ad hoc per programmarlo secondo le nostre specifiche richieste.

Questo è il microcontrollore originale, un SM894051 della SyncMOS :

microcontrollore SM894051 SyncMOS

Il microcontrollore deve principalmente:

  • attivare/disattivare il relè dell’allarme
  • attivare/disattivare il buzzer
  • ricevere il segnale dei tre fototransistor

Per questo motivo ho scelto di utilizzare un PIC12F629 della Microchip, un microcontrollore ad 8pin, essenziale e semplice, ideale per questa applicazione.

Il primo passo è ritagliare un pezzetto di basetta “millefori” per poter adattare il nuovo microcontrollore al vecchio zoccolo:

millefori

Utilizzando una stripline mi sono creato dei piccoli pin per poter connettere la basetta millefori al vecchio zoccolo:

stripline pins

pins nudi

millefori pin zoccolo

Ora è possibile creare lo zoccolo per il nuovo microcontrollore ad 8pin ed effettuare i collegamenti ai vari pin con cavo “wire up”:

wire up cablaggio

Per chi volesse replicare l’hack qui di seguito potete vedere lo schema elettrico e la piedinatura dei due microcontrollori:

In ogni caso però consiglio di verificare la correttezza della piedinatura visto che potrebbe facilmente cambiare da modello a modello.

A questo punto abbiamo tra le mani un perfetto adattatore per installare il nostro nuovo microcontrollore PIC12F629 nello zoccolo originale, senza dover modificare nient’altro!

moduli ir beam

vecchio zoccolo

montaggio ir beam

La parte hardware è praticamente finita! Possiamo iniziare la parte di programmazione!

L’idea di base è di utilizzare tre ingressi per leggere lo stato dei tre segnali dei fototransistor, sfruttando dei pin con funzione IOC (InterruptOnChange) in grado quindi di generare un’interruzione ogni volta in cui avviene un cambiamento di stato degli stessi. Inoltre serve una base tempi per avere un minimo di finestra temporale su cui analizzare i dati, quindi ho scelto di utilizzare il timerZero per generare un’interruzione ad intervalli regolari.

Utilizzo l’ambiente di sviluppo MPLAB v8.7 ed il compilatore HiTech PICC v8.91 LITE quindi includo il file header apposito e creo la prima funzione per inizializzare il sistema:

/************************************************************************************************\

	IRBeam v1.0 - PIC12F629/675
	www.ajk.altervista.com

	Copyright (c) 2013, Alberto Garbui aka AjK
	All rights reserved.

	Redistribution and use in source and binary forms, with or without modification, 
	are permitted provided that the following conditions are met:

	-Redistributions of source code must retain the above copyright notice, this list 
	 of conditions and the following disclaimer.
	-Redistributions in binary form must reproduce the above copyright notice, this list 
	 of conditions and the following disclaimer in the documentation and/or other 
	 materials provided with the distribution.
	-Neither the name of the AjK Elettronica Digitale nor the names of its contributors may be 
	 used to endorse or promote products derived from this software without specific prior 
	 written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
	SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

\************************************************************************************************/

#include	<htc.h>

//fuses
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_OFF & BOREN_OFF & CPD_OFF & CP_OFF & MCLRE_OFF);

//pin connections
#define SENS1	GPIO5 //input sensors [1..3]
#define SENS2	GPIO4
#define SENS3	GPIO3
#define BUZZ	GPIO2 //output buzzer
#define RELE	GPIO1 //output alarm

//configurations stuff
#define ALARM_PULSE		1500	//2000ms -> 2sec
#define WINDOW_WIDTH	20		//80ms
#define TMR0_PRESET		8		//Timer0 preset (prescaler 1:4 -> overflow every 1ms)
#define PULSE_TRIGGER	1		

//global variables
unsigned short tempo;		//time counter
unsigned short C1,C2,C3;	//pulse counters

void systemInit()
{
	// I/O init
	TRISIO=0b111000;
	GPIO=0b000010;
	WPU=0;				//pullUp disabled
	CMCON=7;			//comparator disabled
	//ANSEL=0;			//all digital pins (only PIC12F675)
	IOC=0b111000;		//InterruptOnChange pins (GP3..5)

	//ALARM active LOW (default HIGH)
	RELE=1;

	//BUZZER active HIGH (default LOW)
	BUZZ=0;

	//Timer0 - prescaler 1:4 - 4us steps - overflow every 1ms (with PRESET=8)
	OPTION_REG=0b10000001;

	TMR0=TMR0_PRESET;			
	INTCON=0b10101000;			//Timer0 interrupt + IOC interrupt

	tempo=0;C1=0;C2=0;C3=0;		//counters reset
}

Successivamente scriviamo la routine di interrupt:

static void interrupt isr(void)					
{
	if(GPIF)				//pin changed?
	{
		C1+=(!SENS1);
		C2+=(!SENS2);
		C3+=(!SENS3);
		GPIF=0;				//flag reset
	}
	if(T0IF)				//timer0 overflow?	
	{
		tempo++;			
		TMR0=TMR0_PRESET;	//timer0 reset
		T0IF=0;				//flag reset
	}
}

Ed ora le altre funzioni di supporto assieme al main:

void delay_ms(unsigned short ms)
{
	tempo=0;
	while(tempo<ms);
}

void alarm()
{
	RELE=0;		//active LOW
	BUZZ=1;		//active HIGH
	delay_ms(ALARM_PULSE);	//send alarm pulse
	BUZZ=0;
	RELE=1;
}

void main()
{
	systemInit();

	BUZZ=1;				//start beep
	delay_ms(500);
	BUZZ=0;

	while(1)
	{
		if(tempo>WINDOW_WIDTH)
		{	
			if(C1<PULSE_TRIGGER || C2<PULSE_TRIGGER || C3<PULSE_TRIGGER)
			{

				alarm();
			}
			C1=0;C2=0;C3=0;		//counters reset
			tempo=0;			//time window reset
		}
	}//end while

}//end main

Per chi fosse interessato a ricevere il pacchetto completo (sorgenti+eseguibile) mi contatti privatamente.

Tutto il codice presente in questo sito web è rilasciato sotto licenza BSD-3.

Prima di concludere volevo parlare un po’ a riguardo del modulo radio a 433MHz. La barra ricevente infatti ha un piccolo modulo radio atto ad inviare un determinato codice (preimpostabile) una volta che l’allarme è scattato.

modulo radio

Potrebbe essere una buona soluzione per rilevare un possibile intruso a distanza, ma:

  • personalmente preferisco gestire tutto con un circuito cablato ad anello chiuso, così da rilevare anche possibili manomissioni (taglio dei cavi di alimentazione ad esempio)
  • il modulo radio evita il cablaggio dei cavi per rilevare l’allarme, ma è vulnerabile a disturbatori radio tipo il nanoJammer!

E’ per questi motivi che ho semplicemente dissaldato il modulo radio risparmiando così anche in termini di consumo energetico 🙂 pochi “mW” ma meglio di nulla!

modulo radio rimosso

Alla prossima!