Raspberry Pi GPS tracker – Converting Code to PHP – Part 1

Last week I looked at getting the hardware up and running for a Raspberry Pi GPS tracker. However, as I said I was using some Python code and I don’t speak Python so I wanted to convert it to PHP. So this week I am going to look at what I did.

Before I could even begin to look at the converting the code I had to see if it was even possible for PHP to access the serial port. Turns out this is exactly what Direct IO (dio) is for but it isn’t included as standard so you have to download and install as follows:

First you need the prerequisites which are pear and php5-dev which is required for compiling additional modules:

sudo apt-get install php-pear php5-dev -y

Next download and compile dio:

sudo pecl install channel://pecl.php.net/dio-0.0.7

This will show the following output:

Build process completed successfully
Installing '/usr/lib/php5/20131226/dio.so'
install ok: channel://pecl.php.net/dio-0.0.7
configuration option "php_ini" is not set to php.ini location
You should add "extension=dio.so" to php.ini

Pay particular attention to the last line!

Reading from the serial port is pretty easy and very similar to reading from a file, so to open the port you do the following:

if ( !$t = fopen('dio.serial:///dev/ttyACM0','r+b',false, $c) )  echo 'Failed to open ttyACM0';

Then to read from the port:

$line=fgets($t,1024);

In our case we want to continuously cycle reading the port looking for valid GPS location records.

// cycle round forever looking for the correct GPS record
while(true) {
    // get a record from the GPS
    $line=fgets($t,1024);
    // we are only interested in GPMRC records
    if (!empty($line)){
        if ( strpos($line,"GPRMC")){
            // break up the string
            $resp = explode(",", $line);
            // we are only interested in valid GPS records
            if ($resp[2] == "A") {
                $lat_decimal = degrees_to_decimal($resp[3], $resp[4]);
                $lon_decimal = degrees_to_decimal($resp[5], $resp[6]);
                file_put_contents($logs.date('Ymd').'-simple-log.txt', $resp[9].",".$resp[1].",".$lat_decimal.",".$lon_decimal.PHP_EOL,FILE_APPEND);
            }
        }
    }
}

Rather than reproduce all the code here which will become out of date as I improve it I have published it to Github here.

Next time I will look at some interesting quirks of this and how to improve the code’s usefulness.

Leave a Reply

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