House-Monitoring Framework with Arduino and Raspberry Pi: The Paranoid App - LEKULE

Breaking

28 Jun 2016

House-Monitoring Framework with Arduino and Raspberry Pi: The Paranoid App

So you have a Raspberry Pi and an Arduino and you want to develop a system to monitor and control your home. If I'm reading your mind correctly, after you're done reading this article you will be able to do exactly what you want.
There are plenty of articles on the internet, but most are either too basic or they even skip some of the steps. I will guide you through every step and make sure that you don’t run into any known problems.

Introduction

First of all, why would you want to use an Arduino and a Raspberry Pi together? The Pi has GPIOs that are great for simple Boolean tasks (On or Off) and for reading a cheap temperature sensor. Is that enough? No! For more complex systems, you will want to use a microcontroller to do the heavy work. It has an ADC with multiple channels (Analog to Digital converter), PWM (Pulse Width Modulation) channels, and very accurate timing.
For example, if you want to measure the electric energy consumption of your house, you need a current transformer and a basic circuit that will output a voltage that you can measure using the ADC. If you want to output something in between 1 and 0, let’s say to fade an LED, you would use the PWM outputs. Finally, you need a microcontroller if you need something with very precise timing like a PID system, multiplexing an LED array, or controlling a stepper motor. In our case, we will be using the Arduino Uno as the microcontroller.

BOM and Schematic

For this project, you will need the following:
  • Arduino Uno (Though you can use a different Arduino product if you wish.)
  • Raspberry Pi (I used a Pi Zero, but any will work.)
  • Raspberry Pi power supply
  • SD Card with Raspbian installed (The Raspbian Lite is ok, too.)
  • Sensors and other modules for the Arduino (This will be based on what you'd like to accomplish.)
  • Basic knowledge of Arduino IDE, Raspbian, C/C++, HTML, and javascript (Don't worry. If you already know C/C++, that'll be enough.)
The schematic is not very complicated and it varies depending on what you want to achieve. In this example, I used a temperature/humidity sensor and an LED.



Arduino Code

For the sake of simplicity, I will only show you here how to read temperature and humidity from a DHT11 sensor and how to remote blink an LED. For your actual project, you will want something more complex as this can be done with just a Raspberry Pi. In case you do want to start with this, here is the schematic:



Let’s start with the basics. The data is sent over the serial port at a baud rate of 9600. In the main function, we read the serial port and we check what we receive. If we receive the string “thl”, it means that we need to send the data from the sensors over the serial port. For this function to work properly we use a while loop and send the data over and over again until we receive an “ok” to know that the data has reached the server. If we receive the string “led”, we just blink the LED. Here you can add any function and string you want— just remember to use “thl” for sending data.
What you need to know is that we send data in JavaScript Object Notation (JSON) form. JavaScript Object Notation is an open-source format to transmit data objects. We use this because we can easily use this data within the main.html file using javascript. To use it, we will need a library called ArduinoJson which you can find here or download below. The function “send_data()” does as its name implies: It sends the data over the serial port in JSON form. To add data, you just need to add a line inside this function that looks like this :

                    root["name_of_data"] = function_that_returns_data();
                  

Where the “function_that_return_data()” looks like this:

                    int function_that_return_data(){
  int data;
  //insert code that reads data from a sensor and attributes the value to variable 'data'
return (data);
}

                  

That is all for the Arduino part. Below you can see the exact code that I have written for this particular case with the DHT11 sensor and the LED.

                    //House monitoring framework with Arduino and Raspberry Pi
//Cezar Chirila  
//AllAboutCircuits.com
//epilepsynerd.wordpress.com

#include "ArduinoJson.h"
#include "dht.h"

dht DHT; //give name to your DHT sensor

#define DHT11_PIN A0 //Pin for DHT11 data
#define LED_PIN A1 //PIN for LED

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  String str;
  str = Serial.readString(); //Read serial
  str.toLowerCase(); //Convert to lowercase 
  if (str == "thl") 
    do
    {
      str = Serial.readString(); //Read the serial again
      send_data(); //Call send data function
    } while (str != "ok"); //Continue to send data until we receive an "ok"
  if (str == "led") {
    digitalWrite(LED_PIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);                   // wait for a second
    digitalWrite(LED_PIN, LOW);    // turn the LED off by making the voltage LOW
  }

}
void  send_data()
{
  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  root["temp"] = get_temperature();
  root["humidity"] = get_humidity();
  root.printTo(Serial);
  Serial.println();
}

int get_temperature() // function that return the temperature as an integer
{
  int temperature;

  DHT.read11(DHT11_PIN);
  temperature = DHT.temperature;
  return (temperature);
}

int get_humidity() //function that return the temperature as an integer
{
  int humidity;

  DHT.read11(DHT11_PIN);
  humidity = DHT.humidity;
  return (humidity);
}

                  

Setting Up the Web Server on Raspberry Pi

We will be using the Raspberry Pi as a web server using NGINX. I will guide you through each step to install this, as well as other components that are needed, such as PHP.
Let’s explain some basics. First of all, you need Raspbian installed on your Pi and a network connection. Now, you can either connect a keyboard and a monitor to the board and open up the terminal, or do as I did and do it over SSH. Whichever method you use, remember that all commands need to be run as root; otherwise, you will get a permission error. This is done by writing “sudo” in front. All that being said, let’s start.
First, let’s update the repository and the packages. If you are not familiar with Linux, what this does is update the place from which the packages (applications) are installed and then update them.

                    sudo apt-get update
sudo apt-get upgrade

                  

We want to install NGINX, PHP, and git (optional, but makes your life easier). When asked, type ‘y’ and press enter.

                    sudo apt-get install nginx php5-fpm git
                  

Now, we need to change the default NGINX directory and make it work with PHP. 

                    cd /etc/nginx
sudo nano sites-enabled/default

                  

You need to make that file looks like this:

                    server {
 listen 80; ## listen for ipv4; this line is default and implied
 listen [::]:80 default_server ipv6only=on; ## listen for ipv6
 root /var/www;
 index index.html index.php;
 # Make site accessible from http://localhost/
 server_name _;
 location / {
         index index.html index.php;
  # First attempt to serve request as file, then as 
  # directory, then fall back to the CMS.
  try_files $uri $uri/index.html;  
 }
 
 location /doc/ {
  alias /usr/share/doc/;
  autoindex on;
  allow 127.0.0.1;
  allow ::1;
  deny all;
 }
 location ~ \.php$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi.conf;
        }
}  

                  

Now restart NGINX.

                    sudo service nginx restart
                  

To test that everything is working, make a PHP test page.

                    cd /var/www
sudo nano test.php

                  

And put this into the test.php file:

                    
phpinfo();
?>

                  

Now navigate to Raspberry-Pi-Ip-Address/test.php (Ex: 192.168.0.2/test.php).
If you see a page with PHP info like the one below, then it works and you should proceed to the next step.



If it does not work, then read this part again and check to see if you did something wrong.

The last step is to input this code to allow the user www-data, which is the user that NGINX uses, to access the serial port.

                    sudo usermod -a -G dialout www-data

                  

After this, do one more restart and take a break. You deserve it.

Website Files

Hang in there, we're almost done. You just need to download the files onto your Raspberry Pi and edit them to your needs.
You can manually download the files and put them into /var/www or you can execute this command and automatically download them from github:

                    cd /var/www 
sudo git clone https://github.com/alexonaci/Paranoid/tree/AAC

                  

Now that we have the files, let’s examine them for a moment. Just so you know, we are using bootstrap to model our website so that it is mobile-compatible and looks good.
  • /img folder: Contains thumbnails and the background image for the index page
  • ArduinoCode.ino: The file that contains the Arduino sketch
  • PhpSerial.php: A library for PHP allowing us to communicate over serial with the Uno using PHP
  • Style.css: The CSS for the page
  • Main.html: The most important page that contains the javascript, the buttons, and the visual data
  • Relay.php: The file which initiates communication with the Arduino
You only need to worry about the main.html page; leave the rest as they are. Sure, if you want, you can customize them to your liking— it’s your project after all.
I will explain here how to add items. To add a new button, just add this line:

                    
class
="col-sm-2" class="jobs">

class

="header-default" class="jobs-header">100 src="img/Thumbnail_Image"> id="Name_action" class="btn btn-danger">class="glyphicon glyphicon-off">On/Off
Thumbnail_Image is the path to the image you want to use as the thumbnail (remember to place it in the /img folder). Name_action is the name that you want to pick for your button. You can check the types of buttons you can use here.
Navigate to the bottom of the file where you can see the line "$("#led-button").click(blinkLED);" and add below it:

                    $("#Name_action").click(Function_Name);
                  

Just above it, add the function that relates to it:

                    function Function_Name (){
   $.get(url + "Parameter") 
}

                  

“Parameter” is the string that it will be sent to your Arduino over serial when you press the button. It needs to be associated with a function inside the sketch. We talked about this in the “Arduino Code” chapter.
To add a new item on the screen that will show a value that the Arduino sends, like sensor data, add this type of item :

                    <div class="col-sm-2" class="jobs"//>
      <h2 class="header-default" class="jobs-header"><img width=100 src="img/Thumbnail_image"></h2>
      <h3>Display_data: </h3>
      <div id="DataID"></div>
</div>

                  

Where "Display_data" is the name that will appear before the data, such as "temperature:", and DataID is the identifier.
Remember when I said that we will receive data as JSON? This is where it comes in handy. Search for the “getLuminosityTemperatureHumidity()” function and just add at the end of it:

                    $("#DataID").html(parsedJSON.name_of_data);
                  

Where “name_of_data” is the string that you have chosen for the data in the Arduino Code section.
There is a function that will call this function every 10 seconds and that is it.

                    setInterval(getLuminosityTemperatureHumidity,10000);
                  

You can change the timing if you would like.
All there is left is for me to explain to you is how the relay.php script works. It is open every time a function like “getLuminosityTemperatureHumidity()” calls. In order to work, it uses the PhpSerial library. The first 8 lines that start with "$serial->" are to establish a serial connection to your Arduino.
ATTENTION! Every time this script is executed, the Arduino will reset. If you do not wish for this to happen, simply connect a 10uF capacitor with the negative pin to GND and positive pin to RESET.
Now that we've gotten that out of the way, let's continue. The "sleep(2);" line is needed because the Arduino is unresponsive for the first few moments when we open the serial connection. After that we send the parameter that we received via GET method, "$_GET["command"]", to the Arduino, and if that command is "thl" we read incoming data from the microcontroller. After the data has been received, we send an "ok" and return the data. That's it.
Here is how your project should look after following these steps:




Debugging

If you are having trouble, such as not receiving data, the easiest place to start debugging is right in your browser. You need to be using Chrome for these instructions: Just press F12, go to the Network tab, click on it, press F5 to refresh and click on "relay.php?command=thl". If everything works, the data should appear like in the screenshot below:



Enjoy your house monitoring system. If you have any questions, please put them in the comments section and I will do my best to help you.

Credits


This is a product of the #HomeHackers Hackathon 26.03.2016 held by Academy+Plus, a collaboration between Bira Gabriel, Chindris Mihai, Daniel Lupaescu, Onaci Alexandru, and myself, Cezar Chirila.

No comments: