Create a 3G Pir sensor with a raspberry Pi

Raspberry Pi 3G PIR sensor

Raspberry Pi 3G PIR sensor

Basically, it is something I was looking to do with SigFox, but unfortunately yesterday I bricked my chip because of a wire unsoldered right in the middle of the upload of a new firmware version … By the way, I’ll do it later once it will be fixed.

So I had to built it on a raspberry as a short term solution. Read next to get details

 

Hardware stuff

Basically this hack is requiring a raspberryPI and a PIR sensor like this one at adafruit.

Pir sensor

Pir sensor

This sensor handle a 3.3V LDO regulator and as a consequence you have to plug it on 5V or more. Or, like I’ve done, you can remove the regulator (in the center of the red line), shortcut in/out (yellow line) and makes it working on 3.3V.

Makes Pir operating 3.3V

Makes Pir operating 3.3V

 

 

 

 

 

 

By-the-way, I recommend to connect it on 5V with RPI as you have it. So you will be careful because the next picture with the RPI connectivity will differ.

RPI - PIR connection

RPI – PIR connection

 

Now to connect the PIR sensor with the Rapsberry PI, you have to plug the power cable (vcc & ground) and the Pir out signal to the Gpio 1.

As shown on the picture on the left, the VCC is connected to left row first pin (3.3V) .

GND is connected to right raw 3rd pin

Pir-out is connected to right raw 6th pin (gpio1 eq gpio18)

 

 

 

The second needed component is a 3G modem you can plug over USB to have a bundle looking like this :

Raspberry pi with 3G modem

Raspberry pi with 3G modem

Telecom Stuff

To configure the 3G modem, i based the solution on sakir3g toolkit. To install it, I followed that way :

  • Install PPP
# apt-get install ppp
  • Download the software
# mkdir 3g
# cd 3g
# git clone git://github.com/Trixarian/sakis3g-source
# cd sakis3g-source
  • Edit /usb-modeswitch/usb_modeswitch.h and change #include <libusb.h> for #include <libusb-1.0/libusb.h>
  • Run compilation
# ./compile
# cp build/sakis3gz /usr/bin/sakis3g
  • Now, I create a /etc/sakis3g.conf file with the entry related to my ISP (Free telcom)
APN="free"
SIM_PIN=0000
APN_USER=Free
APN_PASS=Free
  •  The connection can be check by calling
# sakis3g connect

Software stuff

The last step is to manage the motion detection and report the change to a server. The system is designed to work with shell script only to make it simple. GPIO can be accessed directly based on /sys/ virtual filesystem.

The status of the PIR is obtain by calling get_pir_status() function. As it can be interesting to get a PIR location based on the IP address, the function get_my_pos() is using the freegeoip.net service.

The system scan PIR state during about 5 minutes. When during this period, te PIR is active at least one, the status activated will be reported. To preserve the communication, only state change will be reported to the backend.

The 3G connection is tested each time as in my test, the stability of the connection is really low, the modem is hanging up after a few second of transmission. But is work enough time for the application. It’s good !

You have to change the targeted server by yours (part in red in the following script)

#!/bin/sh

base_gpio="/sys/class/gpio/"
pir_gpio=18
pir_path=gpio18

init_gpio() {
  echo ${pir_gpio} > ${base_gpio}/export
  if [ -d ${base_gpio}/${pir_path} ] ; then
     echo "gpio init success"
  else
     echo "[error] gpio init failed"
     exit 1
  fi
  echo "in" > ${base_gpio}/${pir_path}/direction
}

get_pir_status() {
  local v=`cat ${base_gpio}/${pir_path}/value`
  return $v
}

myLat=0
myLng=0
get_mypos() {
  wget -o /dev/null -q -T 5 -O /tmp/geoip.json http://freegeoip.net/json/
  if [ -r /tmp/geoip.json ] ; then
     myLat=`cat /tmp/geoip.json | cut -d "," -f 8 | cut -d ":" -f 2 `
     myLng=`cat /tmp/geoip.json | cut -d "," -f 9 | cut -d ":" -f 2 `
     echo "localisation : ($myLat,$myLng)"
     rm /tmp/geoip.json
  fi
}

main() {
   init_gpio
   get_mypos
   see_last=0
   sent_last=-1
   loop=0
   while true ; do
      # start a 5 min run
      get_pir_status
      s=$?
      if [ $s -eq 1 ] ; then
         see_last=1
      fi

      # check end of period
      if [ $loop -gt 150 ] ; then
         loop=0
         if [ $see_last -ne $sent_last ] ; then
            #check internet connection
            if ! ifconfig ppp0 >/dev/null 2>/dev/null ; then
               sakis3g connect
               get_mypos
            fi
            if ifconfig ppp0 > /dev/null 2> /dev/null ; then
               # mise à jour de l'info serveur
               wget -o /dev/null -O /dev/null -q -T 5 \ 
                  "http://foo.com/?id=0001&time=`date '+%s' `&lat=$myLat&lng=$myLng&rssi=0&data=0${see_last}00000000"
               echo "Nouveau status : $see_last "
               sent_last=$see_last
            else
               echo "Erreur connection Internet postpowned"
            fi

         fi
         see_last=0
      else
         loop=$(( $loop + 1 ))
      fi

      sleep 2
   done
}
main $*

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.