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

 

Advertisements

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

  1. ….just a little UPDATE!!!
    I noticed that after two hours of correct behavior, a strange error message appeared on the shell reporting that “it is impossible to open /dev/ttyAMA0 port, too files opened”.
    Well…. a possible solution is to change python script in order to open only one time the /dev/ttyAMA0 port instead to open/close the port everytime.
    At the same time I noticed that SIM900 module can save only 30 SMS messages, so I added a function that deletes all arrived SMS messages when the total count of messages is major than 20 (I added a margin in order to managfe the SMS arrived automatically from my phone company ! 🙂 ).
    So, the updated script can be (sorry for the incorrect indentation, but I cannot insert it correctly in the comment…do you know a solution?):


    #! /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;

    #poweron the relay
    def PowerONRelay():
    GPIO.setup(22,GPIO.OUT);
    GPIO.output(22,GPIO.HIGH);
    return;

    #poweroff the relay
    def PowerOFFRelay():
    GPIO.setup(22,GPIO.OUT);
    GPIO.output(22,GPIO.LOW);
    return;

    #check unread arrived messages
    def CheckNewUnreadMessage(ser):
    print “Check for new messages..\n”;
    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;
    return response;

    #function to send confirmation SMS
    def SendSMS(ser,value):
    #send SMS about the action
    ser.write(“at\r”);
    time.sleep(3);
    line=ser.read(size=64);
    print line;
    ser.write(‘AT+CMGS=”+3912345678″\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));
    return;

    #function to delete messages…(GSM900 stores only 30 messages..)
    def DeleteAllMsg(ser):
    ser.write(“at\r”);
    time.sleep(3);
    line=ser.read(size=64);
    print line;
    ser.write(‘AT+CMGD=1,4\r’);
    time.sleep(3);
    return;

    #main program —————————————–
    PowerON_SIM900_module();
    print “Registering the sim…\n”;
    time.sleep(15); #wait for sim to resgister to the net

    #open serial link on /dev/ttyAMA0. It is open only one time:it remains open for all operation time.
    #No more open+close action is now requested.
    print “Opening communications serial…\n”;
    ser=serial.Serial(‘/dev/ttyAMA0’,9600,timeout=1);
    ser.open();

    #check continuous loop
    print “Starting main loop\n”;
    arrived_messages=0;
    while True:
    message=CheckNewUnreadMessage(ser);
    if(message.find(“poweron”)-1):
    PowerONRelay();
    #send message to my phone that Relay is ON
    SendSMS(ser, 1);
    print “PowerON commanded\n”;
    arrived_messages=arrived_messages+1;
    elif (message.find(“poweroff”)-1):
    PowerOFFRelay();
    #send message to my phone that Relay is OFF
    SendSMS(ser, 0);
    print “PowerOFF commanded\n”;
    arrived_messages=arrived_messages+1;
    if (arrived_messages>20):
    DeleteAllMsg(ser)
    time.sleep(5);

  2. Pingback: Arduino + Raspberry= Weather station with webcam (Part Four: the internet connection…. and the conclusion!) | ML's Garret Labs

  3. Hi ! Thanks a lot for this tutorial !
    I’ll try this soon !
    Just a little question : how do you take care of the PIN code if needed ?

    – Deminyx

    • Hi Deminyx!
      Thanks to you for your comment! 🙂
      Well…I hate SIM pins :-), so the first thing, before to use a SIM in my embedded projects, I do is to insert a newly bought SIM in a cell phone to disable the pin ! 😉
      Besides, if you want to use the pin of your SIM, it’s simple.
      Before to all other AT commands, after the power ON of the module you should use the following AT commands:

      AT+CPIN?
      Request the current PIN status. It can be one of READY (if the PIN is not requested by the SIM, or it’s already passed to the SIM), SIM PIN (if the SIM requests the PIN to operate), SIM PUK, SIM PUK2 etc.

      AT+CPIN=”pin”
      If the AT+CPIN? reports “SIM PIN”, it is necessary to pass the PIN to the SIM. I.e.: AT+CPIN=”1234″.
      IMPORTANT: AT+CPIN=”pin” returns an error if PIN status is READY, also if the PIN is correct.

      I hope it’s clear…if not feel free to ask all info you want!
      See you!

      • Yep 😉 It’s exaclty what I meant. I’ll see what I can do in the next days. For know I was testing things with 3G keys buy its very unstable.
        I’ll try to redo your tutorial with this :
        Rasp + this GSM Module : http://bit.ly/1rvy6M1 .
        Hope It’s fine.

        If you don’t mind I’ll go back to you, maybe, if there’s any trouble that our friend Google can’t anwser… ;D

        Thanks again !

        – Deminyx

      • That’s good! 😉
        I know your module…the schematic should be the same -or very similar- of mine. I used also a 3G dongle, but with not so good results… (I was using the SMS hi-level software gammu-smsd, search the post in the Garretlabs blog if you are interested! ;-)).
        Good luck with your experiments, and thank to you for interest!
        Marco

  4. Hello there, I finally made it ! It works but I still have one little problem.

    I don’t know how I can use accented letters in my SMS.
    I’m coding using “nano” and it uses only the ascii codec.. I also tried to change the charset used by the module but it failed when I encode my strings every time, Here the part of my code sending SMS, it worked until the message thing :

    #!/usr/bin/python
    #!/usr/bin/env python

    #——————IMPORTATIONS————————

    #….pour dialoguer avec le module GSM
    import serial

    #….pour gerer le temps
    import time

    #—————————————————–
    #.. libEnvoiSMS.py Maxime BELLIER
    #
    #.. Fonction envoyant un SMS depuis le Raspberry v1.5
    #—————————————————–

    def envoyerSMS(numero,messageComplet):

    if len(messageComplet)>160:
    print ” Le message est trop long… Troncature… ”
    messageComplet=messageComplet[0:159]+”+”

    # Formatage message
    # messageComplet=unicode(messageComplet)
    # messageComplet=messageComplet.encode(‘hex’)
    #————————–

    phone = serial.Serial(“/dev/ttyAMA0”, 115200 , timeout=1)
    try:
    print “Connexion au module…”
    time.sleep(1)
    phone.write(‘AT\r’)
    print “OK\n”
    time.sleep(1)
    phone.write(‘AT+CSCS=”8859-1″\r’)
    time.sleep(1)
    phone.write(‘AT+CSMP=17,167,0,0\r’)
    time.sleep(1)
    phone.write(‘AT+CMGF=1\r’)
    time.sleep(1)
    print “Saisie des Champs SMS…”
    phone.write(‘AT+CMGS=”‘ + numero.encode() +'”\r’)

    time.sleep(1)
    phone.write(messageComplet.encode(‘ISO-8859-1’) + “\r”)
    print”OK\n”
    time.sleep(1)
    print”SMS : Envoi OK ! Deconnexion”
    phone.write(chr(26))
    time.sleep(5)
    finally:
    phone.close()

    envoyerSMS(“+3912345678″,u”Yolo ! Hé t’as vu, marche bien frère !”)

    ————————————
    I tried to use unicode strings to encode them afterwards….. Anyway I’m a bit lost right know.. Could you help me ?

    • Hi Max, thanks for you comment!
      Sorry for the late approval/response (et… comme tu peux voir, j’ai changé ce que tu sais! 😉 )
      I’m happy you have resolved the problem… and my answer to your question would be to use just utf-8 instead the other encoding! 🙂
      …Bravo!

  5. Pingback: RasPI-Surv: a Raspberry-based scalable SMS remote controlled video surveillance system | ML's Garret Labs

    • Hi dear bh.seshu.
      Ok… first check (but very important), when you lauch the following code:

      def PowerON_SIM900_module():
      GPIO.setup(17,GPIO.OUT)
      GPIO.output(17,GPIO.HIGH)
      return;

      the SIM900 board correctly powers on? (i.e. the leds power on and they start to blink) If not, the problem can be tied to a broken module…
      If yes,I think there is some communication problem….
      Do you changed the boot line
      dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait
      in

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

      This is very important because this “frees” the pins of serial line of Raspi in order to communicate with the module.
      And, after this, do you deleted the following line from /etc/inittab?
      T0: 23: respawn :/ sbin / getty-L ttyAMA0 115200 vt100

      If yes… after this, this is the last check to do: do you tried to communicate via minicom with module (using paranmeters port: /dev/ttyAMA0, speed: 9600 bps, no flow control, no parity, 8 bit per word, 1 stop bit)? It worked?
      If not, there is still problem on serial communication with module. If yes… we should debug some python code for your case.
      Let me know, in orderto investigate more deeply.
      Bye,
      Marco

  6. Hi.

    What is power consumption under work your module? Have you possibility messure current under work and when modem waiting for SMS?

    Thanks in advanced
    BR.

    • Hi dear yamakasii!
      I’m sorry for the late answer but during these days I’m involved in new projects(=musical instruments design).
      So… reading the Itead docs http://wiki.iteadstudio.com/RPI_SIM900_GSM/GPRS_ADD-ON_V1.0 I see that the average current consumption is 500mA, but during the communication (during the sending of an SMS) I measured max 1A of consumption. For this reason I suggested a power supply with 2A in my post. 😉
      …But the same ITEAD document reports Instantaneous current consumption of 2A for this module. I never measured this value during my experiments… but I think there is some situation it could be measured (phone calls?it is possible).
      Thank you for your comment… and keep in touch with Garretlabs!

  7. Thanks for posting such an interesting project. Looking forward to eventually trying out your other one with the wireless cameras. Unfortunately, I am stuck on this one at the moment.

    Right now I can communicate with the SIM900 chip via AT commands. However, that is as far as things go. No flashy SMS messages coming to my phone from the RPi. Tried two different SIM cards, one of them tied to Telus.

    I am unsure why I cannot get my RPi with the GSM add-on to work on a cellular network, but I think the it is due to one of a few potential problems, from which I will list two: 1) I am using a SIM card that is still locked to a provider in Canada, e.g. there is a SIM PIN that I cannot remove; 2) Potential improper setup or initial configuration of the SIM900 chip (tried to set the APN with ”AT+CGDCONT”). Any advice that you would give is greatly appreciated!

    • Hi dear Warren, sorry for the late answer!
      I think your problem is tied to the SIM card has a unremovable PIN….
      It is important that the PIN of your SIM could be removed or iserted at power on in order to access to SIM card functionalities (eg. send/receive SMS messafes).
      Imagine that SIM900 board is very similar to a mobile phone, so if you don’t insert the PIN before any other operation (i.e. at mobile phone power on), the SIM900 module won’t work.
      Are you sure that the PIN cannot be disabled? You sould try removing it insert the SIM in one mobile phone and disabling the PIN request at phone startup in the setup configurations of the SIM card.
      Or, using AT commands via serial communication, you could try to disable the PIN using these commands:

      AT+CPIN?
      >>> +CPIN: SIM PIN // It meabns that your SIM wants the PIN is entered before operations
      >>> OK

      AT+CPIN=”9546″ //you enter the PIN
      >>>; OK

      AT+CLCK=”SC”,0,”9546″ // thii is the command to disable PIN —>in this example your PIN is 9546
      >>> OK

      AT+CPIN?
      >>> +CPIN: READY //now the PIN is disabled…

      If really the PIN cannot be disabled, at power ON, before sending SMS messages, your software should send (via serial terminal) this command to the SIM900 module:
      AT+CPIN=”9546″ //9546 is your PIN in this example

      Let me know if it has been useful for you.
      Keep in touch with Garretlabs!

      • Hi Marco,

        I ended up getting it to work, or rather realized that it was working already :).

        It did end up being the SIM card. The problem was that the SIM only supported MOMT SMS between other devices/SIMs that are associated to my account. In other words, I couldn’t use that SIM to send SMS to my personal cell.

        Thanks for the troubleshooting tips. Looking forward to trying the camera project.

        Cheers,
        Warren

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s