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://
# 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)
  •  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 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)



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

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

get_mypos() {
  wget -o /dev/null -q -T 5 -O /tmp/geoip.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

main() {
   while true ; do
      # start a 5 min run
      if [ $s -eq 1 ] ; then

      # check end of period
      if [ $loop -gt 150 ] ; then
         if [ $see_last -ne $sent_last ] ; then
            #check internet connection
            if ! ifconfig ppp0 >/dev/null 2>/dev/null ; then
               sakis3g connect
            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 \ 
                  "`date '+%s' `&lat=$myLat&lng=$myLng&rssi=0&data=0${see_last}00000000"
               echo "Nouveau status : $see_last "
               echo "Erreur connection Internet postpowned"

         loop=$(( $loop + 1 ))

      sleep 2
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.