Arduino + Raspberry= Weather station with webcam (Part Four: the internet connection…. and the conclusion!)

…Gooooood morning Vietnam!!!!

Ehmmm…good morning my dear geeks! 😉

A little lapsus is acceptable today, since today we finish the Weather Station project based on Raspberry and Arduino! 🙂 🙂

First thing: if you lost my previous three post on this marvelous project, please, read them: One, two, three! They contain not only the steps to build the weather station, but also general concepts about data acquisition, I2C connection, webcam integration and so on… 😉

Ok, today firstly we connect our weather station to internet. In order to do it we must use a 3G dongle (or a 3G expansion card for Raspberry). Note that the well known SIM900 Raspberry Addon (see my posts on it) is not suitable since it is a GPRS card.

 

The internet connection

For this purpose I used an old 3G dongle by Vodafone (with a SIM card by TIM inside). This dongle is a HUAWEI K3715 (a.k.a E 180).  With an infinite luck 🙂 I noticed that this dongle is automatically recognized as USB modem by Raspbian…. this is not the case of (for example) the HUAWEI E1820 (another dongle that I have at home).

So, the dongle is mapped by Raspbian at /dev/ttyUSB0 (you can verify it with dmesg or lsusb commands).

Let’s go on.

Firstly we must install screen (the AT commands wrapper) and wvdial (the PPP dialer) applications.

#sudo apt-get install screen
#sudo apt-get install wvdial

After this you must modify the /etc/wvdial.conf in order to match your 3G dongle.

In my case (TIM service provider, with HUAWEI K3715 dongle) the file is:

[Dialer defaults]
Init = AT
Init4 = AT0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init3 = AT+CGDCONT=1,"IP","ibox.tim.it"
Phone = *99***1#
ISDN = 1
Username = a
Password = a
Modem = /dev/ttyUSB0
Baud = 460800
Stupid Mode = on

Some mysterious initialization is created ” by default” by wvdial. 🙂

Anyway, note that important lines for your configuration are: Init3 (where I placed my access point ibox.tim.it),  Username and Password (mandatory for wvdial, but with TIM you can insert a dummy user, I placed “a” in both cases), the Modem path and the Phone number (also *99# can work well with  my dongle).

After having saved the configuration file you can launch:

#sudo wvdial

…If all works well you will see the PPP connection steps, the IP address assignment etc. So, opening the browser you could surf on Internet! 🙂

 

The Dynamic DNS

Well, at this point you can surf the Internet, but it’s important to access to your Weather Station FROM Internet.

Since you have a dynamic IP assignment, you must use a service called Dynamic DNS in order to access to your Raspberry using always the same name (for example: mystation.dyndns.org).

In order to do it, firstly you must register to a Dynamic DNS site (I use always http://dyn.com/dns/). Note that Dyn.com is a pay service (but you have 30 days to try it)… and the price is effordable  (25 $ for year, and you can register up to 30 domains).

After this you must install on Raspberry a dynamic DNS client application. I used ddlclient.

#sudo apt-get install ddlclient

The configuration of the app is done launching:

#sudo dpkg-reconfigure ddlclient

You should insert the following parameters:

  • Name of service: http://www.dyndns.com
  • User: the username with wich you registered on Dyn.com (i.e. myuser)
  • Password: the password with wich you registered on Dyn.com (i.e. mypassword)
  • Interface on wich activate the client: ppp0 (it is the PPP on the USB 3G dongle)
  • activate ddlclient when ppp0 starts: Yes
  • Domain: the domain you registered on Dyn.com (i.e. mystation.dyndns.org)

Ok, at this point add to /ect/rc.local the following line, in order to automatically start the internet connection at Raspbian boot:

sudo wvdial &

Weeeeeelllll… this was a ordeal! 🙂

 

The web access from Internet

Do you remember that in my previous post I added the mjpg-streamer web server in rc.local?

So, if all works well, now you will see what your webcam images opening a browser from you Internet connected tablet, phone or pc and writing on the address bar:

http://mystation.dyndns.org:8090

But….what happens if the internet connection goes down? You should try to automatically relauch wvdial (or reboot), or you cannot (NEVERMORE) access to your station.

In order to do it I wrote a little .sh script that checks the internet connectivity.

This is the script:

#! /bin/bash
# Sending the output of the wget in a variable and not what wget fetches
RESULT=`wget --spider http://www.google.it 2>&1`
FLAG=0

# Traverse the string considering it as an array of words
for x in $RESULT; do
    if [ "$x" = '200' ]; then
        FLAG=1 # This means all good
        echo  "Internet OK, Google responded!"
    fi
done

if [ $FLAG -eq '0' ]; then
    # Probably internet key TIM is down...
    echo "Internet down"
    #....triyng to reconnect TIM key
    sudo reboot
fi

It checks if Google is accesible (using wget) from your station, and if not, it forces a reboot. This script must be lauched every X minutes in order to reboot the system if the Internet connection is down (so, to retry the PPP connection process). So, I added it to the crontab:

#sudo crontab -e

And at the end of crontab I added the following line (then I rebooted the board):

*/5 * * * * /home/pi/internet_conn_check/internet_check_daemon_v1.sh

The script is launched every 5 minutes. If the Internet is down, a reboot of the station is commanded. 🙂

 

Mixing meteo data with webcam video

We are at the final steps, boys and girls, so you must do the last effort! 😉

In order to “see” the Arduino meteo data mixed with the webcam images, we must now modify:

  • The Raspberry acquisition application
  • A webpage using Javascript

In the step TWO of my Weather Station project I created on Raspberry a C application to acquire data from Arduino. It was printing the meteo data as output on the shell.

Well, this time I modify the program in order to save the meteo data in a text file. This is the way to communicate to the Weather Station webpage the actual meteo data (i.e. the webpage will read this file and it will display the meteo data mixed with the ).

I know this is a “rough” method, but it is only an idea: you can use your preferred approach. 😉

This is the modified C acquisition program for Raspberry.

 #include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
 
// The PiWeather board i2c address
#define ADDRESS 0x04

//commands
#define TEMP 1
#define HUMI 2
#define PRES 3
#define DEW 4

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
static const char *devName = "/dev/i2c-1";
 
int main(int argc, char** argv) {
 
  printf("I2C: Connecting\n");
  int file;
 
  if ((file = open(devName, O_RDWR))< 0) {
    fprintf(stderr, "I2C: Failed to access %d\n", devName);
    exit(1);
  }
 
  printf("I2C: acquiring buss to 0x%x\n", ADDRESS);
 
  if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
    exit(1);
  }
 
  int command;
  FILE* meteo_data_file;

while (1)
{
  //open file for web page display
  meteo_data_file=fopen("../mjpg-streamer/www/meteo_data_file.txt","w");
  time_t mytime;
  mytime = time(NULL);
  fprintf(meteo_data_file,"%s\n<br>",ctime(&mytime));

  for (command= 1; command<=4; command++) {
    int val;
    unsigned char cmd[16];
 
    //printf("Sending %d\n", val);
 
    cmd[0] = command;
    if (write(file, cmd, 1) == 1) {
 
      // As we are not talking to direct hardware but a microcontroller we
      // need to wait a short while so that it can respond.
      //
      // 1ms seems to be enough but it depends on what workload it has
      usleep(10000);
 
      char buf[5];
      if (read(file, buf, 4) == 4) { //read 4 byte from i2c (a float)
        float value_received;
    
    //convert 4 bytes received into a float
    memcpy((char*)&value_received,buf,4);
/*disable printf on shell... 
     if (command==TEMP)   
        printf("Temperature (°C)= %f\n", value_received );
    if (command==HUMI)   
        printf("Humidity (%)= %f\n", value_received );
    if (command==PRES)   
        printf("Pressure (hPa)= %f\n", value_received );
    if (command==DEW)   
        printf("Dew Point (°C)= %f\n", value_received );
*/
        //write the file used to display values on the webpage
          if (command==TEMP)   
                fprintf(meteo_data_file,"Temperature (C)= %f\n<br>", value_received );
        if (command==HUMI)   
                fprintf(meteo_data_file,"Humidity (perc)= %f\n<br>", value_received );
        if (command==PRES)   
                fprintf(meteo_data_file,"Pressure (hPa)= %f\n<br>", value_received );
        if (command==DEW)   
                fprintf(meteo_data_file,"Dew Point (C)= %f\n<br>", value_received );
      }
    }
 
    // Now wait else you could crash the arduino by sending requests too fast
    usleep(10000);
  }
 //close meteo data file
 fclose(meteo_data_file); 
//one sensors reading every 5 seconds
 usleep (5000000);
} 
  close(file);
  return (EXIT_SUCCESS);
}

FIRST NOTE: I placed the executable as you see from the code, I placed the acquisition executable in /home/pi/ and mjpg-streamer in /home/pi/mjpg-streamer.

SECOND NOTE: I save the meteo_data_file.txt in the /mjpg-streamer/www folder, since I found some difficulty to access other directories from inside the webpage javascript.

Compile with the old command:

gcc -o acquisition_task acquisition_task.c

Then add it to the /etc/rc.local in order to autostart it at boot time.

sudo /home/pi/acquisition_task &

Now, the final step: the webpage meteo.html, which mixes the webcam output with the meteo data.

NOTE: This file must be placed in the /mjpg-streamer/www folder!

Note that I modified one of example provided by mjpg-streamer in order to read and display (using a refresh button) the file containing the actual meteo data. 😉

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>
    <title>MJPG-streamer</title>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <link rel="stylesheet" href="style.css" type="text/css" />
    <script type="text/javascript" src="jquery.js"></script>    
    <script type="text/javascript" src="jquery.rotate.js"></script>
    <!--[if IE 6]>
    <link rel="stylesheet" href="fix.css" type="text/css" />
    <![endif]-->
    <script type="text/javascript">
    
    var phi = 0, flipped = 0, mirrored = 0;

    function setXformClass () {
        $('.xform').each(function(idx,el) {
            el.className = "xform x" +(flipped ? "-flipped":"") + (mirrored ? "-mirrored" : "") + "-rotated-" + phi;
        });
    }
    $(document).ready(function() {
        // set rotation angle phi and toggle rotate class
        $('#rotate').click(function() {
            phi = (phi + 90) % 360;
            setXformClass();
            if (phi % 180) {
                $('.xform-p').addClass('rotated');
            } else {
                $('.xform-p').removeClass('rotated');
            }
        });
        // toggle mirror class component
        $('#mirror').click(function() {
            mirrored = ! mirrored;
            setXformClass();
        });
        // toggle flip class component
        $('#flip').click(function() {
            flipped = ! flipped;
            setXformClass();
        });

//ML:::::when I click on refresh_meteo_data...I print the values of the file!    
$("#refresh_meteo_data").click(function() {
        $.ajax({
            url : "meteo_data_file.txt",
            dataType: "text",
            success : function (data) {
                $(".text").html(data);
            }
        });
    });
    });
    </script>
  </head>

  <body>

    <div id="sidebar">
    <br><br>
    <div class="button" align="center">
            <input type="button" id="refresh_meteo_data" value="Refresh Meteo Data!!" />
    </div>
    <br>
    <div class="text" align="center">
            ...No meteo data acquired at the moment! <br />
    </div>

    </div>

    <div id="content">
      <h1>Garretlabs Meteo Lab</h1>
      <h2>version 1.0 (released by Marco Lastri)</h2>
      <h2>https://garretlabs.wordpress.com</h2>

    <p id="xform">
        <button id="rotate"><div class="btnface"></div></button>
        <button id="mirror"><div class="btnface"></div></button>
        <button id="flip"><div class="btnface"></div></button>
    </p>
    <p class="xform-p"></p>
    <p id="streamwrap" class="xform-p">
        <img id="streamimage" class="xform" src="/?action=stream" />
    </p>

    <p>&copy; The <a href="http://mjpg-streamer.sf.net">MJPG-streamer team</a> | Design by <a href="http://andreasviklund.com">Andreas Viklund</a></p>

</body>
</html>

Ok, I simply added a button “Refresh meteo data” in the sidebar, and I added  a callback which, on each button click, reads the file “meteo_data_file.txt” and prints it on the sidebar of the webpage. I didn’t modify the final line, which reports the original team of mjpg-streamer….it’s a beautiful software and I want to remember once again!

….The final goal!!!

Well, the Garretlabs Weather Station is now ready.

When you open from your tablet, pc etc. the page:

http://mydomain.dyndns.org/meteo.html

you would see (if all works correctly) the following page:

Well...the meteo data on the left of frame will be argument of the next posts! ;-)

Then you can click the button “Refresh Meteo Data” you should see the last acquired meteo data values.

Well… it has been a very long and hard work, but now I can place my final Weather Station at Montecchio, a beautiful place near Firenzuola (in the country of Florence, but it is a very special mountain site).

wpid-20140618_182808.jpg

wpid-20140618_182751.jpg

wpid-20140618_183520.jpg

So…. now I can take my grappa, listening a good progressive rock album (or viewing a  70’s italian horror movie).

I think to deserve a little piece of relax, and you? 🙂

Bye bye babes! 😉

 

Advertisements

Arduino + Raspberry= Weather station with webcam (Part Three: the webcam)

Well boys and girls!

Here we are again…and this time we will SEE something with our project.:-)

I know that finally your voyeuristic tendencies (I know…I know) will be satisfied! 😉

Ok, do you remember the previous posts about meteo station? If not, go to the PART ONE and PART TWO!

Now, it’s time to connect ….the webcam! TA-DA!

I chose a very popular webcam by Logitech (…why? simply because it is cheap and it is natively supported by Debian and Raspbian!): the model is the well known C170, and I bought it on Amazon.it for approx. 19 euros.

The famous :-) Logitech C170

The famous 🙂 Logitech C170

The connection to Raspberry is very simple: connect it to one USB port of Raspi before the board power on, then after the Raspi boot sequence  it should be automatically mapped on /dev/video0 device.

I will use mjpg-streamer to remotely view the webcam stream, so we must to execute some preliminary (but necessary) step.

Firstly we must install SVN client, since mjpg-streamer is not in the Raspbian repository.

#sudo apt-get install subversion

Secondly we must download the mjpg-streamer sources in the Raspberry disk.

#svn co https://mjpg-streamer.svn.sourceforge.net/svnroot/mjpg-streamer mjpg-streamer

The last argument is the local folder where the sources will be saved.

IMPORTANT NOTE: some day ago the svn repository for mjpg-stream should be changed, so svn command should return an error reporting also the NEW svn repository path. You should relaunch svn command using the new/right svn repository path.

After this we must also install libjpeg8-dev and imagemagick.

#sudo apt-get install libjpeg8-dev
#sudo apt-get install imagemagick

After this, we must compile mjpg-streamer entering the folder /home/pi/mjpg-streamer (the sources location) and launch the old (very old 🙂 ) make command.

Cross the fingers ;-)….. and voilà, les jeux sont faits! 🙂

In order to remotely view (i.e. inside Firefox or IE) we must now activate the webserver provided by mjpg-streamer.

The command line (a little difficult to read but it works very well in my case) is:

# ./home/pi/mjpg-streamer/mjpg_streamer -i "/home/pi/mjpg-streamer/input_uvc.so -d /dev/video0 -r 320x240 -f 28" -o "/home/pi/mjpg-streamer/output_http.so -p 8090 -w /home/pi/mjpg-streamer/www" &

Well, only some clarification:

-i defines the input stream string

-d defines the video device (as mentioned, we use /dev/video0)

-r defines the video resolution (320 x 240)

-f defines the frame rate (28 frames/minute)

-o defines the output mode configuration (in this case the http is used)

-p defines the http port (in my case 8090)

-w defines the root for the webserver (where the webpages are placed)

Finally, note that the command should be launched in background (using the “&”).

Note also that some error will appear at command launch because C170 webcam doesn’t support all mjpg-streamer features (i.e. zoom), but NO PANIC. It should work correctly (I hope 😉 ).

Now…the test: type in your browser the following address http://192.168.0.x:8090 (where x is the address of your Raspberry) and you should see the demo page of mjpg-streamer with inside the stream image of your webcam. The live stream can be viewed in the subpages “Stream” or “Javascript”. For my meteo station I modified one of the demo pages in order to add the refresh of meteo data arriving from Arduino….but you will see this in the next episodes! 😉

This is rear garden of my house using mjpg-streamer…it’s a very strange view (from the ground) for my C170:

Well...the meteo data on the left of frame will be argument of the next posts! ;-)

Well…the meteo data on the left of frame will be argument of the next posts! 😉

What’s Montecchio? Ehmmm…that’s the name of the place where I will install the meteo station when it will be ready! 😉

OK, last recommendation: if you want to start automatically the mjpg-streamer webserver, you have to add the above command line to /etc/rc.local, as usual.

…Wellllll! 🙂

All good today, without pain. Strange, very strange…. 😉

So, the work on meteo station is more or less terminated: the only things to activate  for full functionalities are

  • the web page containg at the same time the webcam stream asnd the meteo data took from Arduino via I2C
  • the internet access of Raspberry using a 3G dongle with the aid of a Dynamic DNS service.

…But I ensure you that the difficult parts are already passed without (so high) difficulties.

So, see you soon geeks…keep always in touch with Garretlabs! 🙂