Raspberry Pi Temp Sensor Part 4

In this part of the series we will be looking at how you can access your data using Xcode and then ultimately see your temperature data on your iPhone.

Background

To fully understand this section an understanding of concepts like closures, extensions and working with web data would be very helpful. For this I recommend looking at Apple’s Everyone Can Code materials and specifically the App Development with Swift course. The Apple Book can be accessed here:

books.apple.com/au/book/app-development-with-swift/id1219117996

The main focus would be Chapter 5, but I would recommend spending some time working through all of the book if you are interested in iOS development.

Jump to the End

If you just want to jump to seeing the app running you can download my project here:

You will need to make one change to the code and that is to point the app to connect to your Pi. To do this open the project in Xcode and look for the TemperatureInfoDataController.swift file. On line 16 you will see the following:

let baseURL = URL(string: "192.168.66.11/temperaturejson.php")!

Now change this line to match your Pi’s address.

Once you build and run the project you should see the latest temperature on the first screen and then using the tab bar you can see all records.

The app is very basic at this point but does give you some idea of what you can improve.

More Details

If you would like some further understanding of the project I will make another guide to help break it down a little to help out. In another guide I will also show how to graph the data.

Raspberry Pi Temp Sensor Part 3

In this part of the series we will be looking at creating a PHP web page that will show the data logged in the database in JSON format. This format is easily readable by not only computers but also humans, so it is an excellent way to share data. So lets get on with making the changes we need.

Acknowledgement

The original guide that this post is taken from can be located below.

wingoodharry.wordpress.com/2015/05/18/raspberry-pi-temperature-sensor-web-server-part-3-scheduling-temperature-readings-and-php-script/

Create a PHP web page

First we need to create a file in our web server storage. This is a special area that provides access via a webpage. This is stored in /var/www/html so type:

cd /var/www/html/

Now create PHP file that will display the data in JSON format:

sudo nano temperaturejson.php

The code to pasted into the file is

 PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];
try {
     $pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
$stmt = $pdo->query('SELECT * FROM tempLog ORDER BY datetime DESC');
$tempValue = array();
$i=0;
while ($row = $stmt->fetch())
{
    $dateAndTemps = array();
    $datetime = $row['datetime'];
    $temp = $row['temperature'];
    $dateAndTemps["Date"] = $datetime;
    $dateAndTemps["Temp"] = $temp;
    $tempValue[$i]=$dateAndTemps;
    $i++;
}
echo '{"records":'.json_encode($tempValue).'}';
?>

Now to view your data open a web browser and type the following address but also changing the numbers to match your Pi's address.

[192.168.0.10/temperatu...](http://192.168.0.10/temperaturejson.php)

Note I had to restart my Pi to get this working. You can use the following from SSH

sudo shutdown -r now

If all works you should see something similar to:

JSON Data
JSON Data

Now you are ready for Part 4, where we will make our iOS app to display the Temperature data.

Raspberry Pi Temp Sensor Part 2

Welcome to Part 2 of this guide. To store our temperature values we will need a database, we will use MySQL for this. To access the database online we will need a web server and a script to run on it, Apache and PHP respectively.

Acknowledgement

The original guide that this post is taken from can be located below.

wingoodharry.wordpress.com/2015/01/05/raspberry-pi-temperature-sensor-web-server-part-2-setting-up-and-writing-to-a-mysql-database/

Install the Database and Web Server

To install Apache and PHP on the raspberry pi enter this command, when prompted type "y".

sudo apt-get install apache2 php libapache2-mod-php

Once complete you can test the web server by simply entering the IP address of the Pi into a web browser of a device that is on the same local network as the Pi. You will get the following page if successful:

Now install MySQL by entering the following, press "y" again when prompted.

sudo apt-get install mariadb-server php-mysql

We will also be editing our MySQL database from our Python script in the future so download the corresponding Python library:

sudo apt-get install python-mysql.connector

Run the following command to begin the MySQL securing process.

sudo mysql_secure_installation

Just follow the prompts to set a password for the root user and to secure your MySQL installation.For a more secure installation, you should answer “Y” to all prompts when asked to answer “Y” or “N“. These prompts will remove features that allows someone to gain access to the server easier.Make sure you write down the password you set during this process as we will need to use it to access the MySQL server and create databases and users for software such as WordPress or PHPMyAdmin.Now open MySQL:

sudo mysql -u root -p

You will be prompted to enter the password that we just created for MySQL’s root user.

This logs us in to MySQL as the root userWe will now delete the default mysql root user and create a new mysql root user, because the default one can only be used with Linux root account, and so not available for the webserver and php scripts.To do so, once you connect to MySQL, simply run thoses commands (replace password with the password you want to use) :

We are now going to create a database, I called mine temp_database which is a bit unimaginative. Here is a cheat sheet of MySQL commands too.

CREATE DATABASE temp_database;

Next, we will create a MySQL user that we will assign to our new database. We can create this user by running the following command.For this example, we will be calling the user “tempUser” and giving it the password “tempPassword“. When creating your own, make sure you replace both of these.

CREATE USER 'tempUser'@'localhost' IDENTIFIED BY 'tempPassword';

With the user created, we can now go ahead and grant all privileges to the user so that it can interact with the database.

This command will grant all permissions to our “tempUser” for all tables within our “temp_database” database.

GRANT ALL PRIVILEGES ON temp_database.* TO 'tempUser'@'localhost';

The final thing we need to do for both our MySQL database and user to be finalized is to flush the privilege table. Without flushing the privilege table, the new user won’t be able to access the database.We can do this by running the following command.

FLUSH PRIVILEGES;

We can check this has worked by entering the below. A list of the databases currently held by MySQL will be displayed. Don’t be alarmed if there is more than the one you just created.

SHOW DATABASES;


You should see something similar to:

+——————–+

| Database           |

+——————–+

| information_schema |

| mysql             |

| performance_schema |

| temp_database     |

+——————–+

4 rows in set (0.00 sec)

Now we want to make a new table in the temp_database. To this we firstly have to tell MySQL that we wish to use the temp_database:

USE temp_database;


We now create a table in MySQL using the following commands. MySQL commands are out of the scope of this blog but essentially we are making a table called tempLog that has two fields; datetime (of type DATETIME) and temperature(of type FLOAT). Both must have values (i.e. not null).

CREATE TABLE tempLog(datetime DATETIME NOT NULL, temperature FLOAT(5,2) NOT NULL);


To check that our table is correct we can check by entering the following:

DESCRIBE tempLog;


You will get the following output, describing the table’s fields.

+————-+————+——+—–+———+——-+

| Field       | Type       | Null | Key | Default | Extra |

+————-+————+——+—–+———+——-+

| datetime   | datetime   | NO   |     | NULL   |       |

| temperature | float(5,2) | NO   |     | NULL   |       |

+————-+————+——+—–+———+——-+

Exit MySQL by pressing ctrl z.

Now go to your tempLog directory and add another Python script in nano called readTempSQL.py:

cd tempLog

sudo nano readTempSQL.py


Copy the following code into your new Python script.

import os
import time
import datetime
import glob
import mysql.connector
from time import strftime

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
temp_sensor = '/sys/bus/w1/devices/28-0300a2798953/w1_slave'

# Variables for MySQL
db = mysql.connector.connect(user='tempUser', password='tempPassword', host='localhost', database='temp_database')
cur = db.cursor()

def tempRead():
        t = open(temp_sensor, 'r')
        lines = t.readlines()
        t.close()

        temp_output = lines[1].find('t=')
        if temp_output != -1:
                temp_string = lines[1].strip()[temp_output+2:]
                temp_c = float(temp_string)/1000.0
        return round(temp_c,1)
        
while True:
        temp = tempRead()
        print temp
        datetimeWrite = (time.strftime("%Y-%m-%d ") + time.strftime("%H:%M:%S"))
        print datetimeWrite
        addTemp = ("INSERT INTO tempLog "
                "(datetime,temperature) "
                "VALUES (%s,%s)")
        dataTemp = (datetimeWrite, temp)
        try:
                print "Writing to database..."
                # Execute the SQL command
                cur.execute(addTemp, dataTemp)
                # Commit your changes in the database
                db.commit()
                print "Write Complete"

        except:
                # Rollback in case there is any error
                db.rollback()
                print "Failed writing to database"

        cur.close()
        db.close()
        break

This is a modification of our original Python script but we are adding code to handle the MySQL functionality. Firstly, at the top of the script we add an import for the MySQLdb Python library we downloaded earlier. A bit further down you will see variables that will be used when communicating with MySQL (password, user, host etc) – remember to change them to your variables!

“sql = …” is a string that we will send to MySQL as a command that adds our datetime and temperature values to the tempLog database. There is then a try statement that executes the sql command. If for some reason that fails the except code will run, printing a fail message and discarding attempted changes to the database. Play about with this code and try to change stuff, its the only way I learnt how to it works.

Now run the Python script we just made a few times.

sudo python readTempSQL.py


You should see the following output on your terminal window if all has worked:

pi@raspberrypi ~/tempLog $ sudo python readTempSQL.py

18.6

2015-01-04 22:29:24


Writing to database…


Write Complete


Now lets check that the Python script actually entered data into the MySQL database. Log back into MySQL and USE the temp_database. We can then query the tempLog table:

mysql --user=root --password=yourmysqlpassword


USE temp_database;


SELECT * FROM tempLog;


In the terminal window you will see the following output.

+———————+————-+

| datetime           | temperature |

+———————+————-+

| 2014-12-28 17:26:20 |       18.90 |

| 2014-12-28 17:27:05 |       18.90 |

| 2014-12-28 17:27:52 |       18.90 |

| 2014-12-28 17:30:39 |       19.00 |

| 2014-12-28 17:31:02 |       18.90 |

+———————+————-+

5 rows in set (0.00 sec)

If all has worked, well done! Next we will look at getting the data from the database for our app.

Raspberry Pi Temp Sensor Part 1

Over the last few years I have been teaching a class called Mechatronics that combines together engineering and robotics with a goal for students to build real world technology to solve a problem. In building student learning for open ended tasks, I needed a project that could combine many skills together. I had previously used Arduino's to enable a programmable device with I/O but I was happy bring in other technologies. I had also been coding more and more with Swift and making Apps with Xcode. As my students had also begun their journey with App Development in other classes, I thought it would be a great opportunity to leverage this knowledge and see how I could show live data from a temperature sensor in an App. So this lead me to the path of using a Raspberry Pi to become the hub of the project as I could basically build a database and web server that stored and shared data collected from a temperature sensor. This data could then be shown via an iOS app.

Essentially this series of guides will cover:

  • Setting up a DS18B20 temperature sensor
  • Writing a Python script to read the sensor
  • Setup of LAMP. Linux, Apache, MySQL & PHP for the webserver
  • Writing the values from the temp sensor to the MySQL database
  • Writing PHP scripts to access the MySQL database from a web browser
  • Outputting the results as JSON for a mobile app to read.
  • An simple iOS app to read our temp sensor values and display them

Acknowledgement

Now in my Googling, I came across an excellent website that covered all these requirements. Unfortunately as we followed through the guides we found that due to age we had to make changes along the way and was only solved by spending time on Google looking for answers. With permission, my guides will follow closely to what these guides had instructed. There are so many little changes that it will be easier to reproduce the work rather than identifying the changes needed to get everything working.

wingoodharry.wordpress.com/2014/12/24/raspberry-pi-temperature-sensor-web-server-part-1-intro-sensor-setup-and-python-script/

Download

Once you have your Raspberry Pi you will need to install Raspbian and I also recommend using an app called Etcher to install onto the SD Card.

www.raspberrypi.org/downloads/raspbian/

www.balena.io/etcher/

Once installed the first time you boot your Pi you will be able to run a software update, which I highly recommend. Otherwise you will need to run the following commands from the Terminal:

sudo apt-get update
sudo apt-get upgrade

Also you will need to go into the Raspberry Pi Configuration under Preferences to enable SSH and 1-Wire. Once you have enabled these settings you can remote setup your Pi via SSH (which makes for a much easier experience) rather than using a keyboard, mouse and monitor connected.

To SSH open Terminal and type:

ifconfig

and depending if you are using wifi or Ethernet you will see something like

inet 192.168.0.20

Which really does depend on the network you are using.

On your computer you can then SSH using:

ssh pi@192.168.0.20

Wiring Up

To wire up the circuit you will need a bread board, a 10k Ohm resistor some prototyping wires and the temperature sensor. As I wanted to set this up for an aquarium I used a water proof one:

Waterproof DS18B20 Digital temperature sensor

core-electronics.com.au/waterproof-ds18b20-digital-temperature-sensor.html

The circuit uses 1-wire comms which is great feature because each temperature sensor can be wired to all connect to the same pin on the Raspberry Pi. Apparently you can have up to 75 temperature sensors reading at 1 sec intervals connected straight into the same pin. By default this pin is number 4.

Wiring Diagram
Layout of Wiring

Reading the Temperature Sensor

We need to load the drivers for the 1-wire comms and the temp sensor into the Pi kernel. Modprobe is a Linux program to add a loadable kernel into the Linux kernel. In your terminal enter:

sudo modprobe w1-gpio


sudo modprobe w1-therm

Now change your working directory using the following command:

cd /sys/bus/w1/devices/

This is where the devices running on the 1-wire will be. So to find our newly created device just list the contents of the directory with ls.

ls

Now you should see something listed like

28-00000622fd44 w1_bus_master1

This is the serial number for the device. To interrogate that device we need to go into its directory. Make sure you use the serial number of your own sensor!!

cd 28-00000622fd44

The sensor writes to a file called w1_slave so if we just read that file we can now finally know what temperature it is. Enter:

cat w1_slave

cat simply displays the contents of a file.

You will get the following output:

0b 01 4b 46 7f ff 05 10 a8 : crc=a8 YES


0b 01 4b 46 7f ff 05 10 a8 t=16687

The second line shows the temp “t = xxxxx” in degrees Celsius. This may seem high but that’s because you need to format the data, as the value for t is the temperature to 3dp. So read it as t = xx.xxx . For example 16.687.

Now this is great and all but it’s a bit on the laborious side so lets write a Python script to do all of the hard work for us.

Writing a Python script

Go back to your home directory:

cd ~

and make a new directory called tempLog:

mkdir tempLog

Go into the new directory:

cd tempLog

and create a new python file in nano (which is just a text editing app):

sudo nano getTemp.py

Copy the code below taking care to use your own value for the sensor. Explanation beneath the code.

import os


import time


import datetime


import glob


from time import strftime




os.system('modprobe w1-gpio')


os.system('modprobe w1-therm')


temp_sensor = '/sys/bus/w1/devices/28-00000622fd44/w1_slave'


def tempRead():


        t = open(temp_sensor, 'r')


        lines = t.readlines()


        t.close()



        temp_output = lines[1].find('t=')


        if temp_output != -1:


                temp_string = lines[1].strip()[temp_output+2:]


                temp_c = float(temp_string)/1000.0


        return round(temp_c,1)


while True:


    temp = tempRead()


    print temp


    datetimeWrite = (time.strftime("%Y-%m-%d ") + time.strftime("%H:%M:%S"))


    print datetimeWrite


    break

We first import all of the Python libraries we need. We then load the gpio and therm kernels again using modprobe. Rather than write it out again and again we also use a variable to store our path to the sensor’s w1_slave file, I called it temp_sensor.

A method called tempRead is defined. In this method we read in the w1_slave file using open ‘r’ The file is then converted in to an array of strings called ‘lines’ using readlines.

If you remember it is the second line of the w1_slave file that contains the temperature so we search lines[1] using find for “t=”. Which will give us an index value of where that string occurs. If the returned value from that find is not -1(which means it didn’t find it) we then strip out the temperature reading as a string from the index where “t=” was 2 to the end of the line. If you didn’t 2 you would get “t=xxxxx” as the temperature, we want “xxxxx”.

Then the string is converted to a float, divided by 1000 to put the temperature into proper format of xx.xxx and then returned to the while loop.

When the script is run the first thing it does is go to the while loop. Here it will call our previously defined method tempRead to get the value of the sensor. It will then print the value to the output. Then just to make things look a bit nicer it gets the current date and time and prints it out on the output one line below. Break then stops the while loop and ends the script. I used a while loop so that if you wish you can remove break and insert time.sleep(10) for example so that the temperature and current date and time is output every 10 seconds.

Hopefully that all makes sense. Close the nano file by pressing ctrl and x. It will prompt you to save, press y to confirm writing and the filename.

Now lets give it a go. While still in the tempLog directory enter:

sudo python getTemp.py

You will get something like this:

pi@raspberrypi ~/tempLog $ sudo python getTemp.py
16.4


2014-12-24 11:51:08

We now have the basic workings of our temperature sensor and logger setup. In part 2 we will set up the web server and MySQL table for our data.