Raspberry Pi: Control GPIO and your Pi Camera using your phone

 telegramvideoClick the picture for a video of the project in action

Second article with AutoBoot update added

QUICK TRACK: If you just want to control Sonic Pi with telegram and miss out the GPIO control, then follow the QUICK TRACK pointers.

Today my new Raspberry Pi 2 arrived, and having set it up, I decided to try out this project on it. I noticed it was faster to compile the code and it was nice to be able to have the Epiphany browser open at the same time displaying the instructions in this article. There was one problem, which I think will be quickly solved. The version of the python add-on RPi.GPIO 0.5.9  in the latest version of the Raspian distribution will not run. Instead you need version 0.5.10 or later. Happily the solution is available thanks to an Adafruit blog entry here I have also seen in another comment on this that is is a good idea to upgrade the firmware in the new Pi 2 using sudo rpi-update
Other sources say that the problem should be fixed in the next few days. Having installed the new version of the module, everything worked perfectly on the new Pi 2.

QUICK TRACK: start here Recently my eye was caught by a reference in Pi-Weekly Issue #85 to an article on creating a Raspberry Pi remote control with Telegram. This led me to an instructables article which gave details of setting up an interface to the free site Telegram which is a messaging service with apps for various platforms and phones. The key point was that it was possible to interface with this from a Raspberry Pi which could be used to send and receive messages as if from a mobile phone number. In fact the article led to a github project from vysheng which contained the heart of the telegram code to accomplish this.

The project makes use of the lua language as an interface with which to communicate with telegram programmatically, and by using an associated lua script it is possible to both send messages and also to react to received messages containing a given phrase or command. This in turn allows you to run a python script which can be used control devices connected to the GPIO pins. I also found some alternative versions to this project built around using python to interact directly with telegram, although I eventually went with the lua version as being more flexible. Python based link 1 Python based link 2 as the python examples could only respond to one external command as written.

In the course of setting up the project I encountered some difficulties and misunderstandings which I eventually overcame, and I hope this write-up will enable you to make smoother progress.

Installing telegram

The starting point is the vysheng github project. This has reasonable installation instructions. First you need to install some packages needed to build telegram by typing:

 sudo apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev make

Now you clone the code to your desktop:
(make sure you are in the pi home directory cd ~)

git clone --recursive https://github.com/vysheng/tg.git && cd tg

The recursive call is because two sub-projects tgl and tl-parser are also required. The && cd tg means that you end up in the tg directory ready for the next phase.
Follow this by building the code:

./configure
make

This will take a little time to complete. Just over a minute for the config and about 31 mins for the make phase (on my B+  hopefully quicker on a new B 2 :-) ) It was quicker: 10.5 mins on my Pi2!!, so have a cup of tea once you have started the make phase!

Setting up telegram

Telegram is based on (free) accounts associating a user name and a mobile phone number. In order to set things up you really need access to TWO phone numbers, although thereafter you only need ONE mobile phone to use it. You can set up the Raspberry Pi to use the other mobile phone number that you will not be using. This second phone is only really needed to authenticate the account.
So that you can configure the username you wish to use, it is probably a good idea to install telegram on the mobile phone whose number is to be associated with the Raspberry Pi first. I used an iPhone and downloaded the app (free) from the App Store. It asks you to enter your phone number (with country code eg +44) and it then sends a 5 digit authentication code as an sms which you type into the app. Alternatively if you don’t receive the code it can ring you 2 minutes later and give you the code with an automatic voice. It then asks you for the user First and Last name. Since I wasn’t going to use telegram subsequently on this phone, I assigned a name My (first name) RPi (last name) to this account. You can use whatever you wish. Once you have FULLY set up the Raspberry Pi telegram, you can delete the app from this second phone. (later on in the project)

Back to the Raspberry Pi now, Initially you can test telegram from the inside the folder tg. Later we will move the binary files elsewhere so that they are easier to access and use.
First type the command

bin/telegram-cli -k tg-server.pub

You should see some info printed about telegram, ending with a > prompt on the screen
Press the return key a couple of times and wait
You should then see a prompt phone number:

Type in the phone number of the phone you have just set up, including the country code. eg
+447804123456
Note, you will need access to the mobile phone in order to get an authentication code.
You should then see the response
code (‘call’ for phone call):
After a pause you should get a text on the mobile phone containing a 5 digit code number
Type this number into the Pi terminal and press return, to authenticate it.

Now you need another mobile phone (this time your own one) to have telegram installed on it. The procedure is as for the first phone, although this time you use your own phone number, and probably your own name for the user name. You can add the Raspberry Pi to the contacts list on this installed telegram app, using the name you used on the first phone (in my case My RPi) and the phone number of the first phone.
Now try sending a message from your phone to the first phone. Start a chat with the contact My RPi and type in and send a message. All being well it should be received on the first phone (if you have still have telegram running on it) AND on the Raspberry Pi terminal running telegram. You can reply from the Pi by typing:
msg FirstName_LastName Hi from my Raspberry Pi
where FirstName and LastName are the names for your OWN phone telegram account. In my case Robin_Newman

Note sometimes it can take a little time before the telegram cloud server connects you up. It is worth trying messages in both directions and usually the connection gets going quite quickly.

If this is all working you have successfully set up telegram on the Raspberry Pi as a second device associated with the first telephone number. This is quite legit, and you can in fact have several devices associated with a phone number on telegram. I fact, I also install the desktop version of telegram on my iMac, and can use either my phone, or the iMac to communicate with the Raspberry Pi.
You can exit the telegram program by typing in the command quit at the command prompt, or perhaps better safe_quit which ensures that there are no transactions in progress before quitting.

Making things interactive

First, having got telegram working, you no longer need the use of the first phone which was used to set it up. If you wish you can now remove telegram from this phone. For the rest of this article, when I refer to using the phone, I mean your own phone, or the telegram app installed on your desktop if you have done that.
Having got telegram running, we can now look at how you can interact with it and get it to control devices connected via the GPIO pins, or get it to take a photo with the camera module and send it to a remote terminal client.
As intimated at the beginning of this article there are two mechanisms to do this. One uses just python, but in the examples I have seen it is limited to just one control function. It makes use of the pexpect add-on to python, and there is an example program at the end of the article in Python based link 2
I went with the other method, which is to use the lua programming language which is linked into the original github project. If you look in the tg folder there is a file called test.lua This contains a series of functions which can control how telegram responds to various situations. In particular, it can be used to respond to messages with automated replies, or to launch other programs (eg python scripts) in response to a predefined message being received.

Initially I found that this file did not work properly: After some investigation I determined that there were two further packages which needed to be installed on the Raspberry Pi.
type in:

sudo apt-get install lua-lgi libnotify-dev

Now you can try using the test.lua file
type in:

bin/telegram-cli -k tg-server.pub -s test.lua

This should startup telegram with the line before the prompt saying:
Hi, this is lua script
Before we look at the script, we can try a couple of the procedures already built into it.
From your phone or desktop app send the message ping to your Pi.
You Pi should respond with the reply pong
Secondly send the message  PING (all caps) to your Pi.
This time the Pi will respond with:
Forwarded from Your Name
PING

The contents of the file test.lua are shown below

started = 0
our_id = 0

function vardump(value, depth, key)
  local linePrefix = ""
  local spaces = ""

  if key ~= nil then
    linePrefix = "["..key.."] = "
  end

  if depth == nil then
    depth = 0
  else
    depth = depth + 1
    for i=1, depth do spaces = spaces .. "  " end
  end

  if type(value) == 'table' then
    mTable = getmetatable(value)
    if mTable == nil then
      print(spaces ..linePrefix.."(table) ")
    else
      print(spaces .."(metatable) ")
        value = mTable
    end
    for tableKey, tableValue in pairs(value) do
      vardump(tableValue, depth, tableKey)
    end
  elseif type(value)	== 'function' or
      type(value)	== 'thread' or
      type(value)	== 'userdata' or
      value		== nil
  then
    print(spaces..tostring(value))
  else
    print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
  end
end

print ("HI, this is lua script")

function ok_cb(extra, success, result)
end

-- Notification code {{{

function get_title (P, Q)
  if (Q.type == 'user') then
    return P.first_name .. " " .. P.last_name
  elseif (Q.type == 'chat') then
    return Q.title
  elseif (Q.type == 'encr_chat') then
    return 'Secret chat with ' .. P.first_name .. ' ' .. P.last_name
  else
    return ''
  end
end

local lgi = require ('lgi')
local notify = lgi.require('Notify')
notify.init ("Telegram updates")
local icon = os.getenv("HOME") .. "/.telegram-cli/telegram-pics/telegram_64.png"

function do_notify (user, msg)
  local n = notify.Notification.new(user, msg, icon)
  n:show ()
end

-- }}}

function on_msg_receive (msg)
  if started == 0 then
    return
  end
  if msg.out then
    return
  end
  do_notify (get_title (msg.from, msg.to), msg.text)

  if (msg.text == 'ping') then
    if (msg.to.id == our_id) then
      send_msg (msg.from.print_name, 'pong', ok_cb, false)
    else
      send_msg (msg.to.print_name, 'pong', ok_cb, false)
    end
    return
  end
  if (msg.text == 'PING') then
    if (msg.to.id == our_id) then
      fwd_msg (msg.from.print_name, msg.id, ok_cb, false)
    else
      fwd_msg (msg.to.print_name, msg.id, ok_cb, false)
    end
    return
  end
end

function on_our_id (id)
  our_id = id
end

function on_user_update (user, what)
  --vardump (user)
end

function on_chat_update (chat, what)
  --vardump (chat)
end

function on_secret_chat_update (schat, what)
  --vardump (schat)
end

function on_get_difference_end ()
end

function cron()
  -- do something
  postpone (cron, false, 1.0)
end

function on_binlog_replay_end ()
  started = 1
  postpone (cron, false, 1.0)
end

We only need to concentrate on one function

function on_msg_receive (msg)
  if started == 0 then
    return
  end
  if msg.out then
    return
  end
  do_notify (get_title (msg.from, msg.to), msg.text)
 
  if (msg.text == 'ping') then
    if (msg.to.id == our_id) then
      send_msg (msg.from.print_name, 'pong', ok_cb, false)
    else
      send_msg (msg.to.print_name, 'pong', ok_cb, false)
    end
    return
  end
  if (msg.text == 'PING') then
    if (msg.to.id == our_id) then
      fwd_msg (msg.from.print_name, msg.id, ok_cb, false)
    else
      fwd_msg (msg.to.print_name, msg.id, ok_cb, false)
    end
    return
  end
end

This parses incoming messages and you can see that the two examples we have used for ping and PING are actioned here. When the message ping is received a message pong is returned and when PING is received the same messaged is forwarded back to the originator.
We will add further sections to this function in order to get the functionality we require.

QUICK TRACK: If you only want to control Sonic Pi, you can jump to the section Final Tidying up, before moving to the second article.
First we will add the functionality to send a photo in response to the request message Sendphoto
If you have a Raspberry Pi camera module, then this can be set up to take a fresh photo every time this request is made. If not, you can use any existing photo jpeg and send the same one every time the request is made.
Sending a photo is a built in command in telegram. For example if there is a picture in the tg folder I could send it to my phone by typing
send_photo Robin_Newman photo.jpg where photo.jpg is the filename.
To automate this we can add to the function on_msg_receive  immediately before the final end statement.
So as to preserve the existing file, I used a copy produced by typing cp test.lua rpicontrol.lua You can edit this file either by using the nano editor or, if you start the graphical Interface using startx by opening the file rpicontrol.lua with the leafpad editor under the Menu Accessories.
Before we modify the function on_msg_receive we will add a path variable to the beginning of the file, so that it will be easy to use telegram and the extra python scripts we will develop from any defined location. Immediately after the first two lines which set the variables started and our_id we will insert a line

path = os.getenv("HOME")..""

This will set a variable path to equal the HOME environmental variable which will be set to /home/pi, the home directory of our logged on user. Initially we will put nothing between the two “” following this. Later we will add /telegram.” there and move all the python scripts we will use and this configuration file into a new folder telegram. As we use these python scripts from the on_msq_receive function we will add their locations in terms of this path variable and then we will only have one line to alter later on when we move everything around.
So that we can see what the path variable is currently set to we will add the following line immediately after the line

print ("HI, this is lua script")

in the rpicontrol.lua file

print ("Python scripts, photo.jpg and rpicontrol.lua should be in "..path)

Now we can add the lines to return a photo, added just before the final end statement of the on_message_receive function.

if (msg.text == 'Sendphoto') then
    send_photo (msg.from.print_name, path..'/photo.jpg',ok_cb,false)
    return
end

If you have a Raspberry Pi camera module fitted to your Pi then add as well the line

    os.execute('python '..path..'/takepic.py')

immediately before the line starting send_photo, and this will update the photo using the takepic.py python script which we will look at in a moment. This uses another important feature of the lua language that we can call other programs using the os.execute command from within our lua script.

The modified function will look like this:

function on_msg_receive (msg)
  if started == 0 then
    return
  end
  if msg.out then
    return
  end
  do_notify (get_title (msg.from, msg.to), msg.text)
 
  if (msg.text == 'ping') then
    if (msg.to.id == our_id) then
      send_msg (msg.from.print_name, 'pong', ok_cb, false)
    else
      send_msg (msg.to.print_name, 'pong', ok_cb, false)
    end
    return
  end
  if (msg.text == 'PING') then
    if (msg.to.id == our_id) then
      fwd_msg (msg.from.print_name, msg.id, ok_cb, false)
    else
      fwd_msg (msg.to.print_name, msg.id, ok_cb, false)
    end
    return
  end
  if (msg.text == 'Sendphoto') then
    os.execute('python '..path..'/takepic.py')
    send_photo (msg.from.print_name, path..'/photo.jpg',ok_cb,false)
    return
  end
end

It is beyond the scope of this article to deal with setting up a camera module on your Raspberry Pi, but this link will get you there if you need help.
Assuming that your camera module is setup and working you can type in the following python script using the nano editor. or from the leafpad editor in the GUI.

First switch to the home directory cd ~
Using nano start with
nano takepic.py then enter the text below

#!/usr/bin/python
import time
import picamera
import os
path=os.getenv("HOME")+""  #adjust path for location of this program
with picamera.PiCamera() as picam:
    picam.rotation=90 #adjust as necessary
    picam.start_preview()
    picam.capture(path+'/photo.jpg',resize=(640,480))
    time.sleep(2)
    picam.stop_preview()
    picam.close()

and save the file. In nano you type ctrl-X followed by Y then return
You can give the file execute permissions if you wish using chmod 755 takepic.py although it will be called with sudo python takepic.py so it is not strictly necessary. As in the case of the rpicontrol.lua file I have set up a path variable so that the photo will be saved in the correct place. Initially this is set to the Home directory (/home/pi) but when we move things later then the path line will need to be altered.

First check that this program works. Type python takepic.py
The camera should take a picture and a file photo.jpg should be saved in the pi home directory.
All being well you can now test this with telegram. Switch back to the tg directory: cd tg

Type in:

bin/telegram-cli -k tg-server.pub -s rpicontrol.lua

Now from your phone or desktop telegram app connect to the Raspberry Pi user you have set up and send the message
Sendphoto (nb with a capital S)
Hopefully the camera should take a picture and send it to your phone or desktop telegram app.

Controlling devices via the GPIO pins

I have one of the excellent CamJAM Edikit #2kits which for an amazingly cheap price gives you amongst other things a breadboard, some connectors, two large leds, one red one blue and a buzzer. I extended the rpicontrol.lua file to enable me to control both the leds and the buzzer via telegram.
The fully modified rpicontrol.lua file is shown below

started = 0
our_id = 0
path = os.getenv("HOME")..""
function vardump(value, depth, key)
  local linePrefix = ""
  local spaces = ""

  if key ~= nil then
    linePrefix = "["..key.."] = "
  end

  if depth == nil then
    depth = 0
  else
    depth = depth + 1
    for i=1, depth do spaces = spaces .. "  " end
  end

  if type(value) == 'table' then
    mTable = getmetatable(value)
    if mTable == nil then
      print(spaces ..linePrefix.."(table) ")
    else
      print(spaces .."(metatable) ")
        value = mTable
    end
    for tableKey, tableValue in pairs(value) do
      vardump(tableValue, depth, tableKey)
    end
  elseif type(value)	== 'function' or
      type(value)	== 'thread' or
      type(value)	== 'userdata' or
      value		== nil
  then
    print(spaces..tostring(value))
  else
    print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
  end
end

print ("HI, this is lua script")
print ("Python scripts, photo.jpg and rpicontrol.lua should be in "..path)

function ok_cb(extra, success, result)
end

-- Notification code {{{

function get_title (P, Q)
  if (Q.type == 'user') then
    return P.first_name .. " " .. P.last_name
  elseif (Q.type == 'chat') then
    return Q.title
  elseif (Q.type == 'encr_chat') then
    return 'Secret chat with ' .. P.first_name .. ' ' .. P.last_name
  else
    return ''
  end
end

local lgi = require ('lgi')
local notify = lgi.require('Notify')
notify.init ("Telegram updates")
local icon = os.getenv("HOME") .. "/.telegram-cli/telegram-pics/telegram_64.png"

function do_notify (user, msg)
  local n = notify.Notification.new(user, msg, icon)
  n:show ()
end

-- }}}

function on_msg_receive (msg)
  if started == 0 then
    return
  end
  if msg.out then
    return
  end
  do_notify (get_title (msg.from, msg.to), msg.text)

  if (msg.text == 'ping') then
    if (msg.to.id == our_id) then
      send_msg (msg.from.print_name, 'pong', ok_cb, false)
    else
      send_msg (msg.to.print_name, 'pong', ok_cb, false)
    end
    return
  end
  if (msg.text == 'PING') then
    if (msg.to.id == our_id) then
      fwd_msg (msg.from.print_name, msg.id, ok_cb, false)
    else
      fwd_msg (msg.to.print_name, msg.id, ok_cb, false)
    end
    return
  end
  if (msg.text == 'Sendphoto') then
    os.execute('python '..path..'/takepic.py')
    send_photo (msg.from.print_name, path..'/photo.jpg',ok_cb,false)
    return
  end
  if (msg.text == 'LedOnRed') then
    os.execute('sudo python '..path..'/LedSet.py OnR')
    send_msg (msg.from.print_name, 'Red Led turned on', ok_cb, false)
    return
  end
  if (msg.text == 'LedOffRed') then
    os.execute('sudo python '..path..'/LedSet.py OffR')
    send_msg (msg.from.print_name, 'Red Led turned off', ok_cb, false)
    return
  end
  if (msg.text == 'LedOnBlue') then
    os.execute('sudo python '..path..'/LedSet.py OnB')
    send_msg (msg.from.print_name, 'Blue Led turned on', ok_cb, false)
    return
  end
  if (msg.text == 'LedOffBlue') then
    os.execute('sudo python '..path..'/LedSet.py OffB')
    send_msg (msg.from.print_name, 'Blue Led turned off', ok_cb, false)
    return
  end
  if (msg.text == 'LedOnBoth') then
    os.execute('sudo python '..path..'/LedSet.py OnBoth')
    send_msg (msg.from.print_name, 'Both Leds turned on', ok_cb, false)
    return
  end
  if (msg.text == 'LedOffBoth') then
    os.execute('sudo python '..path..'/LedSet.py OffBoth')
    send_msg (msg.from.print_name, 'Both Leds turned off', ok_cb, false)
    return
  end
  if (msg.text == 'LedFlashRed') then
    os.execute('sudo python '..path..'/LedSet.py FlashR')
    send_msg (msg.from.print_name, 'Red Led Flashed 5 times', ok_cb, false)
    return
  end
  if (msg.text == 'LedFlashBlue') then
    os.execute('sudo python '..path..'/LedSet.py FlashB')
    send_msg (msg.from.print_name, 'Blue Led Flashed 5 times', ok_cb, false)
    return
  end
  if (msg.text == 'LedFlashBoth') then
    os.execute('sudo python '..path..'/LedSet.py FlashBoth')
    send_msg (msg.from.print_name, 'Both Leds Flashed 5 times', ok_cb, false)
    return
  end
  if (msg.text == 'Buzz') then
    os.execute('sudo python '..path..'/Buzz.py')
    send_msg (msg.from.print_name, 'Buzzer alert sent', ok_cb, false)
    return
  end
end

function on_our_id (id)
  our_id = id
end

function on_user_update (user, what)
  --vardump (user)
end

function on_chat_update (chat, what)
  --vardump (chat)
end

function on_secret_chat_update (schat, what)
  --vardump (schat)
end

function on_get_difference_end ()
end

function cron()
  -- do something
  postpone (cron, false, 1.0)
end

function on_binlog_replay_end ()
  started = 1
  postpone (cron, false, 1.0)
end

As you can see, each additional command has a similar section added to the function. It tests for a particular message, and if a match is found sends an os.execute command to either a python program called LedSet.py OR in the case of the Buzz command to a separate python program called Buzz.py These two programs could have been amalgamated into one, but I developed them separately and have kept them so.

You can type in the additions to rpiconfig.lua and also the two programs LedSet.py and Buzz.py but for convenience I have included a download link to a zip file containing all three of these files, and the program takepic.py at the end of this article.
Here is LedSet.py:

#!/usr/bin/python
import RPi.GPIO as GPIO
import sys, time

GPIO.setwarnings(False)
#circuit matches CamJam EduKit #2 Worksheet Two
GPIO.setmode(GPIO.BCM) #use BCM numbering

ledRed= 18 #pin connection used
ledBlue= 24 #pin connection used
GPIO.setup(ledRed,GPIO.OUT)
GPIO.setup(ledBlue,GPIO.OUT)

commandlist=['OnR', 'OffR', 'OnB', 'OffB', 'OnBoth', 'OffBoth', 'FlashR', 'FlashB', 'FlashTwo']
#nexrt section checks args supplied and gives prompt if wrong or no args on command line
if len(sys.argv) < 2:
    print "Syntax sudo python SetLed.py plus one of: OnR, OffR, OnB, OffB, OnBoth, OffBoth, FlashR, FlashB, FlashTwo"
elif sys.argv[1] not in commandlist:
    print "Syntax sudo python SetLed.py plus one of: OnR, OffR, OnB, OffB, OnBoth, OffBoth, FlashR, FlashB, FlashTwo"

for eachArg in sys.argv:
    if eachArg == 'OnR':
        print "Turn On Red"
        GPIO.output(ledRed,1)

    elif eachArg == 'OffR':
        print "Turn Off Red"
        GPIO.output(ledRed,0)

    elif eachArg == 'FlashR':
        print "Flash Red Led"
        GPIO.output(ledRed,0) #make sure ledRed off before flashes
        time.sleep(0.2)
        for x in range(0,5):
            GPIO.output(ledRed,1)
            time.sleep(0.2)
            GPIO.output(ledRed,0)
            time.sleep(0.2)

    elif eachArg == 'OnB':
        print "Turn On Blue"
        GPIO.output(ledBlue,1)

    elif eachArg == 'OffB':
        print "Turn Off Blue"
        GPIO.output(ledBlue,0)

    elif eachArg == 'FlashB':
        print "Flash Blue Led"
        GPIO.output(ledBlue,0) #make sure ledRed off before flashes
        time.sleep(0.2)
        for x in range(0,5):
            GPIO.output(ledBlue,1)
            time.sleep(0.2)
            GPIO.output(ledBlue,0)
            time.sleep(0.2)

    elif eachArg == 'OnBoth':
        print "Turn On Both"
        GPIO.output(ledRed,1)
        GPIO.output(ledBlue,1)

    elif eachArg == 'OnBoth':
        print "Turn On Both"
        GPIO.output(ledRed,1)
        GPIO.output(ledBlue,1)

    elif eachArg == 'OffBoth':
        print "Turn Off Both"
        GPIO.output(ledRed,0)
        GPIO.output(ledBlue,0)

    elif eachArg == 'FlashBoth':
        print "Flash Both Leds"
        GPIO.output(ledRed,0) #make sure ledRed off before flashes
        GPIO.output(ledBlue,0) #make sure ledBlue off before flashes
        time.sleep(0.2)
        for x in range(0,5):
            GPIO.output(ledRed,1)
            GPIO.output(ledBlue,0)
            time.sleep(0.2)
            GPIO.output(ledRed,0)
            GPIO.output(ledBlue,1)
            time.sleep(0.2)
        GPIO.output(ledBlue,0) #reset ledBlue after flashing

And here is the Buzz.py program

#!/usr/bin/python
import RPi.GPIO as GPIO
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
#circuit used identical to CAmJam Edukit#2 Worksheet 2
buzzer= 22 #pin number used
GPIO.setup(buzzer,GPIO.OUT)

for x in range(0,5):
    GPIO.output(buzzer,1)
    time.sleep(0.2)
    GPIO.output(buzzer,0)
    time.sleep(0.2)

These programs should be placed in the Pi home directory, NOT in the tg directory.

The hardware setup

I have used three pins on the GPIO configured as outputs. These are pins 18 and 24 for the Red and Blue led respectively and pin 22 for the positive terminal of the buzzer. A connection to ground is also made to the 5th pin from the end on the inside row of GPIO pins. For convenience I have used exactly the same layout as employed in worksheet 2 from the CamJam Edukit #2. This can be accessed here (scroll down to get the worksheets) and I suggest you make use of worksheet 2 from this link to build the circuit. You do NOT need to set up the program in the worksheet unless you want to try it out, as its actions are fully covered by the LedSet and Buzz programs. For convenience I also have the layout of the circuitry which I have reproduced for my Model B+ using the program fritzing. Note the pin layout for the Model B+ and the earlier Model B is the same, except that the B+ has more pins on the GPIO connector. But the first 13 rows (or 26) pins are the same on both models. Just count the pins form the end FURTHEST AWAY from the USB connector in each case.
BreadBoardConnectionsConnect up the circuit board to the GPIO pins. Test the circuit as follows
From the Pi home directory type:
sudo python LedSet.py OnR
The red led should come on
sudo python LedSet.py OnB
The blue led should come on
sudo python LedSet.py BothOff
Both leds should go out
sudo python Buzz.py
The buzzer should beep 5 times

All being well, you can now try controlling these via telegram
type:
cd tg
bin/telegram-cli -k tg-server.pub -s rpicontrol.lua
you can now send any of the following messages from your phone
LedOnRed   LedOnBlue   LedOffRed   LedOffBlue   LedOnBoth   LedOffBoth   LedFlashRed   LedFlashBlue   Buzz and Sendphoto

You should get a text response in each case, as well as a photo in the last case.

Final tidying up (Optional)

QUICK TRACK: for Sonic Pi Control do this The compilation of telegram-cli in the downloaded git repository builds the application in the sub folder bin inside the tg directory. It is more convenient to transfer it to the directory /usr/local/bin where it will appear in the user’s $PATH variable and be accessible directly with a telegram-cli command. The binaries compiled with the two sub-processes generate and tl-parser also have to be transferred there. In addition the public key accessed by the -k tg-server.pub part of the command line we have used so far can be transferred to the defauilt location in a folder etc/telegram-cli, where it also has to be renamed from tg-server.pub to server.pub
It is safest to move all these file by copying rather than moving. Type the following from within the tg directory.
sudo cp bin/* /usr/local/bin/
sudo mkdir /etc/telegram-cli
sudo cp tg-server.pub /etc/telegram-cli/server.pub

QUICK TRACK: move to the second article here. You don’t need to download any of the files here if you just want to control Sonic Pi

You can also copy the rpicontrol.lua file to the Pi user home directory
cp rpicontrol.lua ~/
Having copied these, you can now tidy away the tg directory. I put mine in a tar archive so that it could be retrieved if necessary
switch to the home directory first
cd ~
tar cvzf tg.tar.gz tg

The resulting tg.tar.gz file can be stored and if required later you can retrieve it using
tar zxvf tg.tar.gz

We now have loose python scripts and the lua file in the home directory. To tidy these up
mkdir telegram and copy the files Buzz.py  LedSet.py  takepic.py and rpicontrol.lua into the new telegram directory. If you have a photo.jpg file in the home folder you can copy that there too. It is overwritten each time a picture is taken.

Finally, before using the files in their new location we have to set the new path in the takepic.py and rpicontrol.lua files. Open each in turn either with the nano editor or with leafpad and adjust then as follows
For takepic.py change the line path-os.getenv(“HOME”)+”” to read
path-os.getenv(“HOME”)+”/telegram”
For rpicontrol.lua adjust the line path = os.getenv(“HOME”)..”” to read
path = os.getenv(“HOME”)..”/telegram”
Be careful. The lines are almost the same but have slightly different syntax, one using a + to add strings the other ..

Now you can run telegram from the home directory by typing
telegram-cli -s telegram/rpicontrol.lua or if you prefer you can run it from the telegram directory by typing telegram-cli -s rpicontrol.lua
One other addition. There is a useful flag -N which you can use which allows you to see the numeric id of each message. There are several commands you can use generally when sending messages from telegram which require you to reference the message number, eg if you want to forward a message. You can use this flag by starting telegram-cli with
telegram-cli -N -s rpicontrol.lua (from the telegram directory)
telegram-cli -help is a useful source of information, as is typing help from within the running application.

All of the files in the telegram folder created in the final section, can be downloaded from a file telegramfiles.tar.gz  Use tar xcvf telegramfiles.tar.gz to extract them into a folder telegram.  You will also have to clone the github site containing the source files for telegram-cli and build the binaries as discussed in the article, and move them and the server.pub keys to the appropriate locations as discussed in the article.

click here to download

click here to see the video

 

Advertisements

53 thoughts on “Raspberry Pi: Control GPIO and your Pi Camera using your phone

  1. Pingback: Remote control your Raspberry Pi using your phone | Raspberry Pi Pod

  2. Hi There. Followed the instructions and look ok “./configure” executes ok but when I type ‘make’ I just get the messge
    “make: *** No Targets specified and no makefile found. Stop.”

    I am in the tg folder when I do this

    Any ideas?

    thanks

      • Are you sure you have installed all the prerequisites?
        sudo apt-get install libreadline-dev libconfig-dev libssl-dev lua5.2 liblua5.2-dev libevent-dev make
        also done a recursive call when installing the git clone
        git clone –recursive https://github.com/vysheng/tg.git && cd tg

        Should work if so.

      • Hi Chris,

        Could you tell me how you solved this? I have run the commands as per what was posted here, but still get stuck at the same point:

        pi@raspberrypi:~/tg $ make
        make: *** No targets specified and no makefile found. Stop.

      • Hi Chris,

        How did you solve your error?
        However, when I execute the ‘make’ command in the Clone GitHub Repository, it gives me this error. make: *** No targets specified and no makefile found. Stop.

        I have tried installing a compiler, deleting the directory and redoing it, but no change.

        Any suggestions? Thanks in advance

  3. Sorry about all the message – Got this all up and running now thanks. Just one small issue. I can send messages from my phone no problem and the pi received and displays them. I can ‘ping’ it and it ‘pongs’ back but if on the pi I try and use the msg command, i doesn’t give any errors but at the same time the message never makes it to my phone. I’ve tried upper case and lower case, real names and user names and also putting @ at the beginning of both but no joy – any ideas?

    • Glad you got it going Chris. It should work with msg First_Lastname this is the message
      Use the First and Lastname as displayed from the ping message you receive. I’m nearly finished with an update to let you boot straight into the program on your Pi. I too have tried it on a B+ and on a Pi2. Works fine on both.

      Robin

    • Worked this out too. The firstName_LastName was neither my account details or my username. Turns out it was actually the contact name my son had for me in his phones (which I’d used to register the second account) contact list! So for him to send me a message he had to send it to “Dad” – ha!

  4. Another question now :)

    I want to return text values back from the python scripts I am calling – is there a simple way of doing this that I am just missing?

    Alternatively do you know of any completely python based solutions?

    Regards
    Chris

  5. This is great stuff – one question is there a way to register the Pi to a different phone, I want to set it up for another phone but can’t see how I can get it to reregister?

    • The registration details are held in the hidden folder .telegram-cli created in the user home directory ~/
      you can see it with ls -a ~
      Quit telegram and then you can delete it with rm -fR .telegram-cli and when you restart telegram a new directory will be created and you will again be asked for a phone number to register as at the start. If you want to be able to switch, then just move the folder elsewhere or rename it. You can subsequently reinstate it and go back to the first identity.

  6. Pingback: 텔레그램 CLI 를 파이썬으로 제어하기 | Hard Copy Arduino (translates: Python CLI to control the telegram | Hard Copy Arduino)

  7. Pingback: Remote Control with Telegram and chipKIT uC32, Basic I/O shield with Raspberry Pi | RedAcacia

  8. hi mr.robin, im newbie in raspberry……i have a few more idea
    -can i use an usb web cam not picamera?
    -how to send periodic snapshot photo from pi to telegram?
    -how to add motion sensing (motion) to your project?
    thats’s it

    thank you for your attention

  9. Hello, very nice tutorial , interesting to control as many things from telegram , I have a query, I hope I can answer, it is the first time I work with LUA and do not understand much at least of coroutines supposedly become like thread. The question is how can activate a security alarm that runs in the background and allow me to continue to interact with messages and to continue turning lights etc , and when the motion sensor activates the alarm Telegram send me a message ” intruder detected ” currently I can do this but when I run my file alarma.py I can no longer interact with telegram file remains running until the alarm is activated and can continue. This I did and in yowsup lua thread but do not know how to do this , I hope someone can help me because I tried and corutine and I’m not result thanks in advance.

    • Hmm. My use of lua is purely in parsing the messages received by telegram, and then triggering various commands as a result. (eg running a separate python script). You are needing the opposite. Using a python script to trigger a message being sent by telegram. I don’t know enough about lua to see how this is done. I imagine it should be possible. You need some form of event handling to be added to deal with external inputs (from python).

  10. Hello, The automatic text response and photo worked fine for me. But if I try to send a message from Pi by shell script it wont work:
    FAIL: 38: can not parse arg #1
    I tried to send text with folloing command:
    sudo /home/pi/tg.sh Marcus_B “your message”
    …and tg.sh:
    #!/bin/bash
    to=$1
    msg=$2
    tgpath=/home/pi/tg
    cd ${tgpath}
    (echo “msg $to $msg”; echo “safe_quit”) | ${tgpath}/bin/telegram-cli -k tg-server.pub -W

    Did I do some mistake or does anyone has a idea why its not working for me? Thanks in advance.

    Marcus

    • Hi,

      Change this line:
      (echo “msg $to $msg”; echo “safe_quit”) | ${tgpath}/bin/telegram-cli -k tg-server.pub -W

      For this one:
      ${tgpath}/bin/telegram-cli -k tg-server.pub -W -e “send_photo ${to} ${msg}”

      It worked for me.
      Regards!

  11. I suspect the quotes ( around “your message” ) are being stripped when entering the ‘tg.sh’

    Try ‘escaping’ the quotes, eg :

    sudo /home/pi/tg.sh Marcus_B \“your message\”

  12. Dear mr Newman,

    What a great tutorial and the part `Sendphoto` works very fine. Now I have a pi noir camera and i wondered if it´s possible to use the motionfunction to send a photo on telegram. I also wondered if it’s possible to create a button on the GPIO to send a picture to Telegram.
    I´m a newby in LUA so i hope you can help me with it.

    Kind regards,

    Stuurtie

    • Yes you can do this. See the second article here https://rbnrpi.wordpress.com/autoboot-for-telegram-and-sonic-pi-jukebox/

      STOP PRESS NEW VERSION OF sonic pi cli is now released which works with Sonic-Pi 2.7 so the following comment no longer applies, provided you have the correct version installed for your SP version.
      However, be advised that the latest version of Sonic Pi (2.7) breaks the operation of the sonic pi cli. I have made the author aware of this and hopefully it can be amended to work again. Currently you need to use Sonic Pi version 2.6 (or earlier) for it to work. Of course, controlling just the gpio pins if that is what you want to do is no problem.

  13. Hi,
    when i send the command (LedOnR or LedOnB) telegram-cli send error messages

    *** lua: rpicontrol.lua:51: attempt to concatenate field ‘last_name’ (a nil value)

    how resolve this problem? Thank you so much

    • Hi . If you still have telegram on your second phone (for the pi number), just edit the user Profile setting on the second phone and insert a surname for the first phone (your number). It’s probably empty field.

  14. hello sir,,,

    thank you for your useful tutorial..it works for me…
    my question…..i did some modification in takepic.py ..i only have an usb webca, not picamera..
    this is my takepic.py

    import RPi.GPIO as GPIO
    import time
    import sys
    import os
    path=os.getenv(“HOME”)+””
    #grab a snapshot
    os.system(“fswebcam -r 640×480 /home/pi/photo.jpg”)

    it runs perfectly in home/pi directory….

    THE problem ..

    if i run the control lua script…..and send message Sendphoto…yes it takes picture BUT save it into the tg directory..instead of than home/pi directory…just like i did before manually

    my lua script

    if (msg.text == ‘Sendphoto’) then
    os.execute(‘python ‘..path..’/takepic.py’)
    send_photo (msg.from.print_name, path..’/photo.jpg’,ok_cb,false)
    return

    how to solve the problem ??

    thank you

  15. It’s a very long time since I wrote this article, well over a year, so I am a bit rusty on it. Perhaps you could alter the lua line
    send_photo (msg.from.print_name, path..’/photo.jpg’,ok_cb,false)
    so that it uses the photo placed in the tg directory if that is where it is being saved. Might just be as simple as send_photo (msg.from.print_name,’photo.jpg’,ok_cb,false)
    I don’t have this set up any more so can’t test or check things easily.

  16. pi@raspberrypi:~/tg $ bin/telegram-cli -k tg-server.pub
    Telegram-cli version 1.4.1, Copyright (C) 2013-2015 Vitaly Valtman
    Telegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license’.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show_license’ for details.
    Telegram-cli uses libtgl version 2.1.0
    Telegram-cli includes software developed by the OpenSSL Project
    for use in the OpenSSL Toolkit. (http://www.openssl.org/)
    I: config dir=[/home/pi/.telegram-cli]
    > telegram-cli: tgl/mtproto-utils.c:101: BN2ull: Assertion `0′ failed.
    SIGNAL received

    please help

  17. pi@raspberrypi:~/tg $ bin/telegram-cli -k tg-server.pub
    Telegram-cli version 1.4.1, Copyright (C) 2013-2015 Vitaly Valtman
    Telegram-cli comes with ABSOLUTELY NO WARRANTY; for details type `show_license’.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show_license’ for details.
    Telegram-cli uses libtgl version 2.1.0
    Telegram-cli includes software developed by the OpenSSL Project
    for use in the OpenSSL Toolkit. (http://www.openssl.org/)
    I: config dir=[/home/pi/.telegram-cli]
    > telegram-cli: tgl/mtproto-utils.c:101: BN2ull: Assertion `0′ failed.
    SIGNAL received

  18. Hello, first of all thank you, it works for me, it is working, I’m new with lua, so I was wondering if you could help me with this:

    I want to send a telegram to my phone when a button is pressed. I know how to read a botton in python, but I don’t know how to run the code into lua and obtain data.

    • Hi Mauricio It’s long time since I looked at any of this, so I can’t answer you easily. I too was a newbie at lua when I started this. However, sine the article was written telegram has introduced bots and recently a second generation of bots. If you google this (Telegram Bot Platform), I think this may give an easier way of doing what you wish to do.

  19. – when I run:

    sudo bin/telegram-cli -k tg-server.pub -s rpicontrol.lua

    – then send a message:

    LedOnRed, LedOnBlue, etc.

    -then:

    [sudo] password for telegramd:

    -my password

    -then:

    telegramd is not in the sudoers file. This incident will be reported.

    as resolved?

  20. hi,
    Thank you for this app, I am completely new to lua. Is there any possibility to include mobile number in the program, so the raspberry pi will respond if the message is from only that mobile number.

    • Hi! It’s long time since I looked at any of this, so I can’t answer you easily. I too was a newbie at lua when I started this. However, sine the article was written telegram has introduced bots and recently a second generation of bots. If you google this (Telegram Bot Platform), I think this may give an easier way of doing what you wish to do. This article is now quite old, and a lot has changed with telegram.

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