News:

The Latest electronic and computer Tips that work!

Main Menu

Raspberry PI as remote Temperature Measurment

Started by branx86, April 24, 2017, 11:59:04 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

branx86

From:  http://geek.adachsoft.com/home/article/id/17/n/Raspberry-PI-with-DS18b20-web-server-PHP-Remote-temperature-measurement/refid/gp

How to make remote temperature measurement using Raspberry PI, DS18B20, PHP and PostgreSQL. This projection will show you how to easily make a temperature logger using the above technology. The entire temperature logger will be made using the PostgreSQL database. I will also show the example of a working online temperature logger on my website.
Step 1: Components

Raspberry PI
DS18b20
Some wires
Step 2: Requirements

In this project we will need installed:
Apache2
PHP
PHP PDO
PHP PostgreSQL
Install the apache2 package by typing the following command in to the Terminal:

   sudo apt-get update
   sudo apt-get install apache2
Then we install PHP.

   sudo apt-get install php5 libapache2-mod-php5
Install the PostgreSQL.

   sudo apt-get install php5-pgsql
Step 3: Connection of the temperature sensor

The DS18B20 sensors can be connected in parallel. The resistor 4.7k is used as a pullup for the data-line, and is required to keep the data transfer stable. All sensors should share the same pins, and you only need one 4.7K resistor for all of them.
Diagram of connection of temperature sensor DS18B20.
Diagram of connection of temperature sensor DS18B20.
Diagram of connection of temperature sensor DS18B20.
Diagram of connection of temperature sensor DS18B20.
NOTE: In newer versions of the system, add the following entry to /boot/config.txt and restart the Raspberry PI.

   dtoverlay=w1-gpio,gpiopin=4
With this command we can check the attached devices for one wire.

   cat /sys/bus/w1/devices/w1_bus_master1/w1_master_slaves
To read the temperature from sensor, type the following command, replace device_id with your device identifier.

   cat /sys/bus/w1/devices/[device_id]/w1_slave
Step 4: Database creation

Now create a simple database containing only two tables.

Below the table in which we will store the connected devices.
Field   Description
name   Friendly name
dev_id   Device identifier

   CREATE TABLE w1_devices
   (
     w1_devices_id serial NOT NULL,
     name character varying(128) NOT NULL, -- Friendly name
     dev_id character varying(64) NOT NULL, -- Device identifier
     CONSTRAINT w1_devices_pkey PRIMARY KEY (w1_devices_id),
     CONSTRAINT w1_devices_dev_id_key UNIQUE (dev_id)
   )
Table containing temperature measurements.
Field   Description
date_insert   Measurement time
w1_devices_id   Row identifier from table "w1_devices"
temperature   The value of the measured temperature
date_check   Time of the last measurement.

   CREATE TABLE temperature
   (
     temperature_id serial NOT NULL,
     date_insert timestamp with time zone NOT NULL DEFAULT now(),
     w1_devices_id integer NOT NULL,
     temperature numeric(10,2),
     date_check timestamp with time zone,
     CONSTRAINT temperature_pkey PRIMARY KEY (temperature_id),
     CONSTRAINT temperature_w1_devices_id_fkey FOREIGN KEY (w1_devices_id)
         REFERENCES w1_devices (w1_devices_id) MATCH SIMPLE
         ON UPDATE NO ACTION ON DELETE NO ACTION
   )
Step 5: Script in PHP

Below is a script that will be executed every minute, via cron. This script measures the temperature of the sensors (DS18B20),
then compares the value of the measurement to the previous value. If the difference is greater than 0.1 degrees Celsius,
it inserts a new record into the table "temperature". If the difference is less than 0.1 degree celsius. This does the update of
the last measurement by changing the value of "date_check". I put this file in /var/www/html/

Before using these scripts, you need to configure your connection to the database server. I use an external
database on my server, but you can also use a local database on the Raspberry PI.

   $dbname='';
   $host='';
   $dbuser='';
   $dbpass='';
File temp.php
<?php
   error_reporting(E_ALL);
   ini_set('display_errors', 1);

   $dbname='';
   $host='';
   $dbuser='';
   $dbpass='';
   try {
      $db = new PDO("pgsql:dbname=$dbname;host=$host", $dbuser, $dbpass);
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   }catch(PDOException $e){
       echo "ERROR: " . $e->getMessage();
   }
   
   //----------------------------------
   $str = file_get_contents('/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves');
   $dev_ds18b20 = preg_split("/\\r\\n|\\r|\\n/", $str);
   
   
   foreach( $dev_ds18b20 as $val ){
      if( $val!='' ){
         //echo "DS18B20: $val
\r\n";
         $temp_path = "/sys/bus/w1/devices/$val/w1_slave";
         $str = file_get_contents($temp_path);
         if( preg_match('|t\=([0-9]+)|mi', $str, $m) ){
            $temp = $m[1] / 1000;
            //echo "temp=$temp
\r\n";
            SaveMeasurement( $db, $val, $temp);
         }
      }
   }
   //----------------------------------
   
   function SaveMeasurement($db, $dev_id, $temp){
      try {
         $sql = $db->query ("SELECT * FROM w1_devices WHERE dev_id='$dev_id'");
         $result = $sql->fetch( PDO::FETCH_ASSOC );
         if( $result===false ){
             die('You must first define the device: ');
          }else{
             $sql = $db->query ("SELECT * FROM temperature WHERE w1_devices_id='$result[w1_devices_id]' ORDER BY date_insert DESC LIMIT 1");
            $result = $sql->fetch( PDO::FETCH_ASSOC );
            $ins = true;
            if( $result!==false && abs($result['temperature'] - $temp) < 0.1 ){
               echo abs($result['temperature'] - $temp);
               $ins = false;
            }
            
            if( $ins ){
               $sql = "INSERT INTO temperature(w1_devices_id, temperature) VALUES(:w1_devices_id, :temperature)";
                $statement = $db->prepare($sql);
               $statement->bindValue(':w1_devices_id', $result['w1_devices_id']);
               $statement->bindValue(':temperature', $temp);
               $statement->execute();
               $statement->closeCursor();
            }else{
               $sql = "UPDATE temperature SET date_check=now() WHERE temperature_id=:temperature_id";
                $statement = $db->prepare($sql);
               $statement->bindValue(':temperature_id', $result['temperature_id']);
               $statement->execute();
               $statement->closeCursor();   
            }
             
          }
      }catch(PDOException $e){
          echo "ERROR: " . $e->getMessage();
      }
   }
?>
Now we will create a shell script.

   cd /var/www/html/
   nano cron_temp.sh
   chmod +x cron_temp.sh
File cron_temp.sh
php -f /var/www/html/temp.php
Then we add this file to corn.

   crontab -e
We add this line and save.

   * * * * * /var/www/html/cron_temp.sh
Saving the results of temperature measurement every minute should already work. Now display the results from the table "temperature".
For this purpose we write another two scripts.
File ds18b20.php
<?php
   error_reporting(E_ALL);
   ini_set('display_errors', 1);

   echo "time: " . time() . "\r\n
";

   $str = file_get_contents('/sys/bus/w1/devices/w1_bus_master1/w1_master_slaves');
   $dev_ds18b20 = preg_split("/\\r\\n|\\r|\\n/", $str);
   
   
   foreach( $dev_ds18b20 as $val ){
      if( $val!='' ){
         echo "DS18B20: $val
\r\n";
         $temp_path = "/sys/bus/w1/devices/$val/w1_slave";
         $str = file_get_contents($temp_path);
         if( preg_match('|t\=([0-9]+)|mi', $str, $m) ){
            $temp = $m[1] / 1000;
            echo "temp=$temp
\r\n";
         }
      }
   }
   
   $dbname='';
   $host='';
   $dbuser='';
   $dbpass='';
   try {
      $db = new PDO("pgsql:dbname=$dbname;host=$host", $dbuser, $dbpass);
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   }catch(PDOException $e){
       echo "ERROR: " . $e->getMessage();
   }
   
   
   ?><div style="background-color: #a0a0a0; vertical-align: bottom;"><?php
   $sql = "
         SELECT * FROM (
            SELECT * FROM temperature ORDER BY date_insert DESC LIMIT 35
         ) AS T ORDER BY date_insert
         ";
    foreach ($db->query($sql) as $row) {
        ?><div style="display:inline-block; margin-right: 1px; background-color: #66b3ff; vertical-align: bottom; width: 50px; height: <?php echo 2 * $row['temperature']; ?>px;"><?php echo $row['temperature']; ?></div><?php

    }
   
?></div>
To automatically refresh the results every second, we use Jquery and AJAX.
File index.php
<?php
   error_reporting(E_ALL);
   ini_set('display_errors', 1);
   
   $dbname='';
   $host='';
   $dbuser='';
   $dbpass='';
   try {
      $db = new PDO("pgsql:dbname=$dbname;host=$host", $dbuser, $dbpass);
      $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   }catch(PDOException $e){
       echo "ERROR: " . $e->getMessage();
   }
   
?><html>
  <head>
    <title><?php echo exec('hostname'); ?></title>
   
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
   <script type="text/javascript">

      function check(){
         $.get( "ds18b20.php", function( data ) {
              $( "#result" ).html( data );
             
            });
      }
      
   </script>
   <script type="text/javascript">
   <!--
      setInterval( "check()" ,1000);
   //-->
   </script>
   
   
  </head>
  <body>

  <div id="result"></div>

  </body>
</html>
Download source code: all-files.zip
Step 6: The end

Below the table with temperature measurements. The sensor is mounted in my living room and the temperature update is one minute.
date_insert   temperature   date_check
2017-04-24 19:52:43   21.63 ℃   
2017-04-24 19:51:42   22.00 ℃   
2017-04-24 19:50:42   22.25 ℃   
2017-04-24 19:41:42   22.50 ℃   2017-04-24 19:49:42
2017-04-24 19:36:43   22.38 ℃   2017-04-24 19:40:43
2017-04-24 19:32:42   22.25 ℃   2017-04-24 19:35:42
2017-04-24 19:30:43   22.13 ℃   2017-04-24 19:31:42
2017-04-24 19:29:42   22.00 ℃   
2017-04-24 19:28:43   21.88 ℃   
2017-04-24 19:26:43   21.63 ℃   2017-04-24 19:27:43
2017-04-24 19:24:43   21.75 ℃   2017-04-24 19:25:43
2017-04-24 19:22:42   21.88 ℃   2017-04-24 19:23:42
2017-04-24 19:19:42   22.00 ℃   2017-04-24 19:21:43
2017-04-24 19:18:42   21.88 ℃   
2017-04-24 19:17:43   21.75 ℃   
2017-04-24 19:16:42   21.56 ℃   
2017-04-24 19:15:42   21.44 ℃   
2017-04-24 19:14:42   21.56 ℃   
2017-04-24 19:13:42   21.88 ℃   
2017-04-24 19:10:43   22.00 ℃   2017-04-24 19:12:42
2017-04-24 19:05:42   21.88 ℃   2017-04-24 19:09:43
2017-04-24 19:03:42   21.75 ℃   2017-04-24 19:04:42
2017-04-24 19:02:43   21.56 ℃   
2017-04-24 19:00:42   21.38 ℃   2017-04-24 19:01:42
2017-04-24 18:58:43   21.19 ℃   2017-04-24 18:59:43
2017-04-24 18:57:42   21.00 ℃   
2017-04-24 18:56:42   20.81 ℃   
2017-04-24 18:55:42   20.56 ℃   
2017-04-24 18:50:42   20.31 ℃   2017-04-24 18:54:42
2017-04-24 18:45:43   20.44 ℃   2017-04-24 18:49:42
2017-04-24 18:31:43   20.31 ℃   2017-04-24 18:44:43
2017-04-24 18:29:43   20.44 ℃   2017-04-24 18:30:43
2017-04-24 18:18:44   20.31 ℃   2017-04-24 18:28:43
2017-04-24 18:03:43   20.44 ℃   2017-04-24 18:17:42
2017-04-24 17:58:42   20.56 ℃   2017-04-24 18:02:43
2017-04-24 17:30:42   20.69 ℃   2017-04-24 17:57:42
2017-04-24 17:20:42   20.81 ℃   2017-04-24 17:29:42
2017-04-24 17:13:43   20.94 ℃   2017-04-24 17:19:43
2017-04-24 17:08:42   20.81 ℃   2017-04-24 17:12:43
2017-04-24 17:06:42   20.94 ℃   2017-04-24 17:07:42
2017-04-24 17:02:43   21.06 ℃   2017-04-24 17:05:42
2017-04-24 16:52:42   20.94 ℃   2017-04-24 17:01:43
2017-04-24 16:51:43   20.81 ℃   
2017-04-24 16:39:42   20.94 ℃   2017-04-24 16:50:43
2017-04-24 16:34:42   21.06 ℃   2017-04-24 16:38:43
2017-04-24 16:33:42   20.94 ℃   
2017-04-24 16:32:42   21.06 ℃   
2017-04-24 16:25:43   20.94 ℃   2017-04-24 16:31:42
2017-04-24 16:15:43   21.13 ℃   2017-04-24 16:24:43
2017-04-24 16:11:43   21.25 ℃   2017-04-24 16:14:43
2017-04-24 16:05:43   21.13 ℃   2017-04-24 16:10:42
2017-04-24 15:54:43   21.00 ℃   2017-04-24 16:04:43
2017-04-24 15:49:43   21.13 ℃   2017-04-24 15:53:42
2017-04-24 15:40:42   21.25 ℃   2017-04-24 15:48:42
2017-04-24 15:39:43   21.44 ℃   
2017-04-24 15:38:43   21.69 ℃   
2017-04-24 15:37:43   22.25 ℃   
2017-04-24 15:06:42   23.00 ℃   2017-04-24 15:36:43
2017-04-24 14:48:43   22.88 ℃   2017-04-24 15:05:42
2017-04-24 14:44:42   22.75 ℃   2017-04-24 14:47:42
2017-04-24 14:42:43   22.56 ℃   2017-04-24 14:43:43
2017-04-24 14:41:43   22.69 ℃   
2017-04-24 14:37:43   22.81 ℃   2017-04-24 14:40:43
2017-04-24 14:35:43   22.69 ℃   2017-04-24 14:36:42
2017-04-24 14:34:42   22.50 ℃   
2017-04-24 14:33:42   22.38 ℃   
2017-04-24 14:28:43   22.56 ℃   2017-04-24 14:32:43
2017-04-24 14:24:43   22.38 ℃   2017-04-24 14:27:43
2017-04-24 14:22:43   22.50 ℃   2017-04-24 14:23:43
2017-04-24 14:21:43   22.63 ℃   
2017-04-24 14:20:44   22.75 ℃   
2017-04-24 14:17:42   22.88 ℃   2017-04-24 14:19:43
2017-04-24 14:14:42   22.75 ℃   2017-04-24 14:16:42
2017-04-24 14:12:42   22.63 ℃   2017-04-24 14:13:42
2017-04-24 14:11:43   22.50 ℃   
2017-04-24 14:10:43   22.38 ℃   
2017-04-24 14:07:42   22.19 ℃   2017-04-24 14:09:43
2017-04-24 14:03:42   22.38 ℃   2017-04-24 14:06:43
2017-04-24 13:59:43   22.25 ℃   2017-04-24 14:02:43
2017-04-24 13:57:42   22.13 ℃   2017-04-24 13:58:43
2017-04-24 13:56:42   22.31 ℃   
2017-04-24 13:55:42   22.56 ℃   
2017-04-24 13:53:42   22.44 ℃   2017-04-24 13:54:42
2017-04-24 13:52:42   22.69 ℃   
2017-04-24 13:50:43   22.81 ℃   2017-04-24 13:51:43
2017-04-24 13:47:43   22.69 ℃   2017-04-24 13:49:43
2017-04-24 13:46:42   22.56 ℃   
2017-04-24 13:45:42   22.38 ℃   
2017-04-24 13:44:42   22.25 ℃   
2017-04-24 13:42:43   22.06 ℃   2017-04-24 13:43:42
2017-04-24 13:39:43   22.19 ℃   2017-04-24 13:41:43
2017-04-24 13:38:43   22.31 ℃   
2017-04-24 13:34:43   22.50 ℃   2017-04-24 13:37:43
2017-04-24 13:32:42   22.69 ℃   2017-04-24 13:33:42
2017-04-24 13:31:42   22.56 ℃   
2017-04-24 13:29:42   22.38 ℃   2017-04-24 13:30:43
2017-04-24 13:28:42   22.63 ℃   
2017-04-24 13:27:42   22.81 ℃   
2017-04-24 13:26:42   22.94 ℃   
2017-04-24 13:22:43   23.13 ℃   2017-04-24 13:25:42