Camera di sorveglianza

Da raspibo.
Jump to navigation Jump to search

Vorreste trasformare il vostro Raspberry Pi in una camera di sorveglianza per controllare quel che succede in un'altra stanza o il garage? Ecco un po' di strumenti che possono esservi utili.

ATTENZIONE: sebbene sia possibile controllare questo dispositivo tramite internet, dovete essere sicuri di quello che fate, essendo possibile che malintenzionati possano collegarsi alla vostra cam per controllare se siete in casa. Inoltre, se la collocate in un luogo pubblico, dovete segnalarla (potete vedere un po' di informazioni sulla privacy qua[1]).

Camera pantilt.JPG

Quel che vi serve:

  • Un Raspberry Pi collegato in qualche modo a una rete (se usate il Wi-Fi potete usare anche un mod. A)
  • Il modulo camera per Raspberry Pi o una Webcam USB
  • Due servocomandi (opzionale)
  • Una struttura pan-tilt (opzionale)

Su Raspberry Pi vanno installati:

  • Raspbian, come sistema operativo
  • MJpegStreamer[2], per lo streaming video
  • ServoBlaster[3] (opzionale), per muovere i servocomandi
  • Lighttpd[4] (opzionale), per fare una semplice interfaccia web

Il pan-tilt

Per la struttura ho scaricato e stampato questo Super Compact Pan Tilt Camera Mount trovato su Thingiverse. Ci sono molti altri modelli che possono andare bene per il modulo camera del Raspberry Pi. Questo purtroppo si è dimostrato abbastanza fragile per molti pezzi è stato necessario essere ristampati perché nel montaggio si erano rotti.

MJpegStreamer

MJpegStreamer è un programma che vi permette di vedere lo stream del modulo cam del Raspberry da una comoda interfaccia grafica via web. Per installarlo potete seguire questa guida sul forum ufficiale del Raspberry Pi. Una volta lanciato lancerà un server web sulla porta 8080 dove sarà possibile accedere a diversi tipi di streaming e ad alcuni controlli sulla qualità dell'immagine. Per collegarvi scrivete http://<indirizzo del Raspberry>:8080.

Purtroppo per farlo funzionare con il modulo camera del Raspberry Pi occorre installare l'API v4l2 per il modulo cam tramite il driver uv4l-raspicam[5]. Una volta installato uv4l e uv4l-raspicam la cam del Raspberry sarà vista come un device /dev/videoX (di solito video0, se non avete altre webcam USB collegate). Se invece usate una webcam collegata all'USB non dovrete installare nient'altro.

ServoBlaster

ServoBlaster è una ottima libreria per la gestione dei servocomandi usando il PWM software. In breve: i servocomandi hanno tre pin, due sono +5v (ma bastano anche 3,3) e la terra, il terzo è il cavo dati, sul quale va mandato un PWM che determina la posizione del servo. ServoBlaster può essere lanciato come demone tramite il comando servod. Fate attenzione che i pin gestiti da ServoBlaster non possono essere usati da altre applicazioni, per cui, se vi servono, dovrete lanciare il demone servod con l'opzione --p1pins=X,Y,Z. Il numero del pin è il numero FISICO, 1 è il +3,3 in alto a sinistra. Per terminare ServoBlaster (utile nel caso i vostri servo siano usciti di controllo!) terminatelo con pkill o killall. ServoBlaster crea un device su /dev/servoblaster il quale riceve i comandi da dare ai servo con questa sintassi:

echo <numero servo>=<PWM> > /dev/servoblaster

il numero servo è dato dall'ordine in cui sono stati inseriti nell'opzione p1pins, ad es. se si scrive:

servod --p1pins=10,7,11

il servo 0 è sul pin 10, il servo 1 è sul pin 7 e il servo 2 è sul pin 11. Se non usate l'opzione p1pins la mappatura di default è, nell'ordine: 7 11 12 13 15 16 18 22. ServoBlaster dovrebbe gestire fino a 8 servocomandi contemporaneamente.

Il PWM farà spostare il vostro servo più o meno a seconda del valore. Nei servocomandi normali il servo si muoverà in una determinata posizione, nei servo continui il PWM determinerà la velocità e il senso di rotazione.

Muovere la camera

Con la libreria curses è possibile creare una interfaccia via ssh. Fate attenzione ai valori passati a ServoBlaster: se fossero stati servo normali avremmo dovuto memorizzare da qualche parte la posizione. In genere con 150 sta nel mezzo, ogni valore inferiore lo muove in un senso, ogni valore superiore lo muove nell'altro senso. Più il valore è lontano da 150 più l'angolo fra la metà e il fine corsa sarà ampio. Con i servo continui invece 150 lo tiene fermo, ogni valore superiore a 150 lo fa girare in un lato, ogni valore inferiore lo fa girare nell'altro lato. Più il valore si distanzia da 150 più rapidamente girerà. Fate attenzione, se usate i servi non continui, al fatto che il motore resta in tensione fino a che non avrà raggiunto la posizione richiesta. Se per caso lo usate per muovere qualcosa che fa molta resistenza (ma non dovrebbe essere il caso del nostro pan-tilt) potrebbe scaldare molto ed eventualmente bruciarsi. Per evitare questo potete chiudere temporaneamente ServoBlaster.

#!/usr/bin/python
import curses
import time
import os

scr = curses.initscr()
curses.cbreak()
curses.noecho()
scr.keypad(1)
curses.curs_set(0)  #inizializzazione dell'interfaccia curses
os.system("sudo /home/pi/servod --p1pins 7,11,12") #chiama ServoBlaster
scr.refresh()
key=0

def stop():
    time.sleep(0.02)
    os.system("echo 0=0 > /dev/servoblaster") #dare valore zero ferma i
    os.system("echo 2=0 > /dev/servoblaster") #servocomandi
    curses.flushinp() #vuota lo stream dell'input

while (key != 27): #27 e' il codice del tasto ESC, premendo ESC si esce
    key = scr.getch() #prende un carattere dall'input della tastiera
    if key == curses.KEY_RIGHT:
        os.system("echo 0=120 > /dev/servoblaster")
        stop()
    elif key == curses.KEY_LEFT:
        os.system("echo 0=160 > /dev/servoblaster")
        stop()
    elif key == curses.KEY_UP:
        os.system("echo 2=120 > /dev/servoblaster")
        stop()
    elif key == curses.KEY_DOWN:
        os.system("echo 2=160 > /dev/servoblaster")
        stop()
    else:
        stop()

curses.endwin()
os.system("sudo killall servod")

Questo sistema è rapido e responsivo, ma per muovere la camera in questo modo e allo stesso tempo vedere cosa sta succedendo dovete tenere aperta la finestra di MJpegStreamer e un ssh al Raspberry Pi contemporaneamente, con l'accortezza di avere a fuoco l'ssh. Non è molto comodo.

Una piccola pagina CGI Python

Lighttpd è un efficace web server orientato alla leggerezza, quindi adeguato per il Raspberry Pi. Usando una guida come questa[6] potrete abilitare il Python CGI in modo da poter mandare i comandi tramite la pagina web. Il codice per muovere i servi è questo:

#!/usr/bin/python
import os
import time
import cgitb
import cgi
cgitb.enable()
form = cgi.FieldStorage()
os.system("echo 2="+form['pan'].value+" > /dev/servoblaster")
os.system("echo 0="+form['tilt'].value+" > /dev/servoblaster")
time.sleep(0.1)
os.system("echo 2=0 > /dev/servoblaster")
os.system("echo 0=0 > /dev/servoblaster")
exit()

Questo codice prende due variabili da un form di una pagina HTML, 'pan' e 'tilt', e li passa a ServoBlaster. Dopo un decimo di secondo spegne i servo ed esce. Il codice della pagina HTML è questo (elimino le parti non interessanti). Per prima cosa creo dei pulsanti che chiamano la funzione 'turn' passando i valori da mandare a ServoBlaster e un div vuoto invisibile:

<button type="button" onclick='turn("0","152")'>lt</button>
<button type="button" onclick='turn("0","140")'>rt</button>
<button type="button" onclick='turn("140","0")'>up</button>
<button type="button" onclick='turn("152","0")'>dn</button>

Poi scrivo la funzione in javascript:

<script type="text/javascript">
   function turn(a,b){
                  document.getElementById('comando').innerHTML = "<object type='type/html' data='pantilt.py?pan="+a+"&tilt="+b+"'></object>";
   }
</script>

La funzione richiama il comando pantilt.py, mandando le variabili 'pan' e 'tilt' via GET, scrivendo dentro al div invisibile.

Se volete avere l'immagine di MJpegStreamer nella stessa pagina, potete sempre creare una pagina Python e sostituire l'indirizzo del server con os.environ['SERVER_NAME']

import os
import cgi
print """
   «vario codice HTML»
   <img src="http://
"""
print os.environ['SERVER_NAME']
print """
   :8080/?action=stream" />
   «altro codice HTML»
"""

Se poi volessimo mantenere anche le altre funzioni di MJpegStreamer possiamo copiare le pagine già fornite con il pacchetto e aggiungere i nostri pulsanti.