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.
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.
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.
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 :
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 $*