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

The dark side of porting Arduino sketches on Intel Galileo (part three: comparing Galileo and Arduino on realtime performances)

Hi dear geeks and Intel Galileo lovers!

I’m sorry if I abandoned for a while your preferred board…but as you know Garretlabs (and I) have many other interests (Raspberry based projects, music and so on…).

Today I want to front one of “dearest” problems of my life: the realtime behavior and characteristics of  boards.

I know, it is one of my preffered psychiatric problems: I want ALWAYS to know the realtime performaces of a board (and of his operating system, if present)  😉

So, this time I want to compare the realtime performances of Arduino UNO and Intel Galileo.

In order to do it, I used the most simple circuit that I know (and that YOU know): one blinking led.

Well, the circuit in Fritzing is:

test_realtime_Galileo_vs_UNO_bbAnd the software is the same (obviously) for both boards:

void setup() 
{
    pinMode (2,OUTPUT);
}
void loop() 
{
   digitalWrite(2,HIGH);
   delay(10);
   digitalWrite(2,LOW);
   delay(10);
}

So, the behavior of code should be very very (very) simple: 10 milliseconds the led is ON and 10 milliseconds it is OFF. So the GPIO2 output is a 5V square wave, with a period of 20 milliseconds  and a duty cycle of 50%.

I connected the channel 1 of my oscilloscope to TestPoint1 and the channel 2 to TestPoint2.

As you see the behavior of the two boards are very different: since the square wave of Arduino UNO (TestPoint 1) is fixed on the timeline with a period of 20 milliseconds, the square wave of Galileo is moving on the timeline and it has more long period than 20 milliseconds. It means that the period is not exactly 20 milliseconds, and it is variable.

This is the trace for Arduino UNO:

Oscill_arduino

As you see, the square wave is perfect (…note that the horizontal scale is 10 milliseconds for division)!

This is the trace for Intel Galileo (stopped in a certain moment, since the trace is continously shifting right):

Oscill_galileo

Well...in this case the square wave  has a period major than 20 milliseconds (because each half wave has a duration major than 10 milliseconds).

Plus, if we measure two random periods, they havent the same duration (the continuous shift of the trace is depending on this).

These are both waveforms:

Oscill_arduino+galileo

So, for me the result is clear: since Arduino UNO commands GPIOs using a very strict realtime, Galileo does not command GPIOs with a realtime scheduling politics.

The motivation can be probably tied to the fact that Galileo launches Arduino scripts as Linux user processes (as I noticed in my prevoius post), so without realtime characteristics.

My conclusion is that, at the moment, we can’t use Galileo as hard realtime controller for particular hardware (ie. safety critical mechanisms and so on). 😦 …

And what are your thinkings about this behaviour of Galileo? Have you found my same results?

Obviously, possible solutions and workarounds are welcome (I thinked to modify the Intel Galileo native Linux in order to add some realtime extension, i.e. RT-PREEMPT or Xenomai).

So, the discussion is open! Let me know what you think! 🙂

…Bye bye electro-babes!

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! 🙂

 

Raspberry and the remote controlled relay: a low-level approach (a.k.a. “AT modem commands: the usual suspects”).

Hi my dear microelectronics F&M (female & male) friends! 😉
Here we are again with the remote controlled 220V relay using a Raspberry PI. In my previous post I used a Huawei 3G dongle with the famous gammu daemon as SMS receiver.
But… do you remember the end of the post? I was talking about a thriller/horror movie by the great Lucio Fulci.
So, the horror turned to real, since gammu-smsd, after 20-25 minutes of correct activity, decided to die himself, without any clear cause. Or better, it continued running in background but when a SMS arrived, the daemon did nothing.
I tried to “reanimate” it in several ways, removing the screensaver and the blank screen from the Raspberry, writing a script which stop/restart the daemon every 5 minutes etc. But nothing changed. 😦
I noticed also after the above mentioned 20-25 minutes, the daemon start/restart (using sudo /etc/init.d/gammu-smsd start/restart) fails.
Only a reboot works in this case….but NO PANIC please! 🙂

I think there is some problem in gammu-smsd (related to Raspbian memory management? Hmmmm…I dont want investigate it because I want to live again 😉 ).
So….I decided to try another approach, using a more simple hardware and writing myself a more simple (= with a simple maintance and debug phases) software.
I bought the ITEAD GSM Sim900 module for Raspberry PI from my usual store (Robot Italy). Price: 37 euros. I think it is a good price for a GSM/GPRS phone without keys and display! 😉
I placed my SIM in the module, then I placed the module on the Raspberry.
The module reports the unused GPIOs on the higher side, so I connected the three wires used to command the relay (Vcc, GND and command) directly to the SIM900 module.
Note that the Vcc available on the SIM900 module is 3.3V , but I noticed that my relay module works well also using 3.3V instead the requested 5V. 🙂
Note also that GPIO18 used to command the relay in my previous post, is used now by SIM900 module as software reset, so I modified my relay ON/OFF scripts in order to use GPIO22.

This is the schema of SIM900 module used GPIOs:Mappatura RasPi GPIO-ITEAD SIM900
Ok, let’s go powering the Raspberry board (with a 2A minimum power supplier, since the SIM900 can use also peaks of current of 1A).
But firstly I needed the right soundtrack for this activity, and the right soundtrack in this case is “The City Sleeps”, a powerful and aggressive crossover-progressive rock cd, in my opinion the best work of Touchstone, the band of my friend Kim Seviour.

Let’s return to us… now the Raspberry boots up but the SIM900 module is powered off (no green led is ON on the surface).
There are two ways to power it on:

  • the first approach is to simply press the power on button :-). Too simple for me.;-)
  • the second way is to set the GPIO17 high….well, you know this is my preferred solution. 😉

The python code (remember you must before install python extensions devoted to GPIO commanding, following my previous post!) is the following:

#poweron the RPI GSM SIM900 module
def PowerON_SIM900_module():
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,GPIO.HIGH)
    return;

Raspberry talks with SIM900 module via a serial link mapped on /dev/ttyAMA0, but Raspberry locks this port at startup. The document reporting the correct actions to free the serial port (before to try to talk with the module) are in ITEAD provided C library…but they are written in chinese! 😦
So I googled aroud a lot before to find the solution to this problem, damn! 😦
This is the correct procedure in order to “unlock” /dev/ttyAMA0 port (application note taken from ITEAD blog, related to another ITEAD product):

In /etc/bootline.txt change:

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait

to:

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait

and in /etc/inittab comment out or delete the following line (in my case it is the last line):

# T0: 23: respawn :/ sbin / getty-L ttyAMA0 115200 vt100

Well…after this, a reboot is necessary.

The Itead GSM module...with "The City Sleeps" of Touchstone!

The Itead GSM module…with “The City Sleeps” of Touchstone!

Now, I tried using the examples provided in the official C library from ITEAD, but I encountered some error (very strange errors, such as “SIM not registered, some unpredictable error code and so on…), so I decided to talk directly to SIM900 module using AT commands.

Firstly I installed the old, well known minicom software then I connected minicom to SIM900 module with the following (the “old style values”) parameters: port: /dev/ttyAMA0, speed: 9600 bps, no flow control, no parity, 8 bit per word, 1 stop bit.

I sent some famous AT commands, such as “AT” (in order to verify if the momdem is responding), “AT+CMGS” (in order to send to my phone a text SMS), etc. and I verified that all worked well.

Quasi-incredible! 🙂

At this point I decided to implement (in Python, of course) the main code, which: receives the SMS message (many thanks to this tutorial for inspiration of this part), parses them and, if a valid command is received, it powers ON/OFF the relay. Plus, the script can send to my phone  a SMS reporting the action (Power ON/OFF) executed.

I used only three AT simple commands:

  • AT (in order to verify if the communication between module and Raspberry is OK)
  • AT+CMGS (used to send SMS messages)
  • AT+CMGL= “REC UNREAD” (used to read received unread messages)

Note that I added some delay, since I noticed that in some case the modem is a little slow to execute the AT commmands and to reply. This is the complete Python code.

But first don’t forget to install the python extension for serial communication using sudo apt-get install python-serial.

#! /usr/bin/env python

import serial
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

#poweron the RPI GSM SIM900 module
def PowerON_SIM900_module():
    GPIO.setup(17,GPIO.OUT)
    GPIO.output(17,GPIO.HIGH)
    return;

def PowerONRelay():
    GPIO.setup(22,GPIO.OUT);
    GPIO.output(22,GPIO.HIGH);
    #send message to my phone that Relay is ON
    SendSMS(1);
    return;

def PowerOFFRelay():
    GPIO.setup(22,GPIO.OUT);
    GPIO.output(22,GPIO.LOW);
    #send message to my phone that Relay is OFF
    SendSMS(0);
    return;


def SendSMS(value):
   #send SMS about the action
   ser=serial.Serial('/dev/ttyAMA0',9600,timeout=1);
   ser.open();
   ser.write("at\r");
   time.sleep(3);
   line=ser.read(size=64);
   print line;
   ser.write('AT+CMGS="+39123456"\r');
   time.sleep(3);
   if (value==1):
       ser.write('Relay powered ON!\r');
   elif (value==0):
       ser.write('Relay powered OFF!\r');
   time.sleep(3);
   ser.write(chr(26));
   ser.close();
   return;

def CheckNewUnreadMessage():
   print "Check for new messages..\n";
   ser=serial.Serial('/dev/ttyAMA0',9600,timeout=1);
   ser.open();
   ser.write("at\r");
   time.sleep(3);
   line=ser.read(size=64);
   #print line;
   ser.write('AT+CMGL="REC UNREAD"\r')
   time.sleep(3);
   response=ser.read(size=200);
   print response;
   ser.close();
   return response;

#main loop
   PowerON_SIM900_module();
   print "Registering the sim...\n";
   time.sleep(15); #wait for sim to resgister to the net
   print "Started main loop\n";
   while True:
      message=CheckNewUnreadMessage();
      if(message.find("poweron")<>-1):
          PowerONRelay();
          print "PowerON commanded\n";
      elif (message.find("poweroff")<>-1):
          PowerOFFRelay();
          print "PowerOFF commanded\n";
     time.sleep(5);

As you see from the code, the new, unread SMS messages are checked every 5 seconds.

If a new message is found, it is copied in the message variable. If the message contains the poweron keyword the relay is powered ON. Else,  if it contains the poweroff keyword, the relay is powered OFF.

In both cases a SMS is sent to my phone (well… this is not my real number, also if I know you would like to know it! 😉 )

In order to auto-start the script after the Raspberry boot, you should add this command to /etc/rc.local (prior, remember to “executabilize” 😀  your script using the old chmod +x name_of_your_script.py ):

sudo /home/pi/name_of_your_script.py &

IMPORTANT NOTE: Add the “&” in order to launch in background the Python script, or you won’t be able to stop it neither using CTRL+C or swithcing shell . I will re-take the control of your Raspberry only via remote connection (using ssh)! 🙂

Now, rebooting the Raspberry, you will be able to receive/send SMS message using AT commands, power ON/OFF a 220V relay…and the most important thing: I tested the system for 3+ hours, and it worked well all time!!!

So ….I think we executed today another litlle step in my and in your “knowledge database system” called BRAIN. 🙂

Now I will take a relax time with the aid of the new Touchstone cd: “Oceans of Time”. It’s an kick-ass prog-rock album, of highest level guaranteed (as we say in Italy, it’s “Lemon guaranteed”, that is “Garantito al limone”).

Bye bye Raspberry freaks, it’s rock time for me! 😉