Navigation

Friday, 12 July 2013

My first Robot! An Ongoing Project - 2

So, I just wanted to put an update on where the project is at the moment. On the last post I pretty much said the robot couldn't move because I stupidly bought the wrong type of motor. I solved that problem and spent a fortune on two continuous rotation servos. I also changed the chassis. No real reason for that I just thought a metal one would be better. The new chassis now has three platters so that I can fit more stuff on it. I have mounted the Raspberry Pi and a a RPi camera board. I have managed to power the Raspberry Pi via the 5v line that power the servos however I think that the servos draw to much current because every time the servos move, the Raspberry Pi turns off... So my next task is to use another 5v regulator and will power it off the battery that is powering the Arduino and hope it has enough power to run both.
On the bright side the robot moves really smoothly now and is current programmed to run a set of commands i.e. go forward, backward etc. I will soon decide on which sensors to use and get it thinking for itself. Peace.

Raspberry Pi Surveillance System: An Overview of What I Did

For my final year project I made a surveillance system using the Raspberry Pi. I aim for this post to just be an overview of what I did.

I'm just going to dive into this. This first thing I did was order a Raspberry Pi. When that came I tried to look for some tutorials, I messed around with it for awhile but after a few days I found the MagPi. MagPi is a free online magazine with all the latest news on the Raspberry Pi including tutorials. One of those tutorials showed you how to make a door sensor. So this is the first prototype I made for the system:
The IDC connector is where the Raspberry Pi connects into. On the board there are 2 indicator LED's which shows the active or inactive states of the system, a buzzer and an input button. The white wire connects to the reed switch but I'd cut it off by this point as I needed it for another model.

Now that I had a greater understanding on how to build the hardware for this project and a good foundation to start, I set out to make a new, better, smaller model. This time it had a PIR sensor. A PIR sensor is very easy to use because all you need to do is check to see if the data pin is high or low. If it is high, it has detected something. I wanted to keep to the 'hobbyist theme' so I put it in an Altoids mint tin. Here it is:




The Circuitry was pretty much the same as the older model, I'd just learnt how to mount it all closer together and be more space efficient. The only difference this model had that the prototype didn't was the PIR sensor that used the 5v pin and an extra IO pin. So obviously the next task was to write the software for it. In the time it had taken me to get from the prototype to this model, I'd also gotten better at programming in Python. I will try and find a way to post my code... I might just post it at the end of this post :/.

The following thing I did was create the user interface. Now for this I made an overly fancy website with multiple user log in and a nice graphical design. I didn't need to do this but I wanted to show that I had those skills. I used the .NET framework with C#. The website had multiple user log in and a way to bind the hardware to the website. All of the users and their details where stored in a SQL database. Here are some screenshots:
I used session cookies for persistent log in 

The next fundamental aspect of the system was to be able to control the hardware from the website. For this I used a python library called WebIOPi. It's a REST based framework designed for the Raspberry Pi and when you install the package it sets up a web server. On that web server is a HTML file linked with a JavaScript file. In the JavaScript file I re wrote it to have two buttons. I then tied it to my Python script so that the buttons would call my Python functions. Its a really good tool I would recommend having a play with it. I then presented this HTML file with the JavaScript buttons on the website via an iframe and gave it the src to the webserver in the C# file like this:
Buttons.Attributes["src"] = "http://192.168.0.11:9898/";
My final important requirement was to make the user aware via email. For this my python code took advantage of the smtplib library. This library allows you to send emails from your script. To do this I used Googles SMTP server which meant I had to make another email account. The code is as follows:
def sendEmail(sensor):
try:
smtpserver = smtplib.SMTP('smtp.gmail.com', 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
try:
smtpserver.login("rpi.alert.infor@gmail.com", "PASSWORD HERE")
except (smtplib.SMTPException), e:
print e
smtpserver.close()
except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
print e

to = "rabostock92@googlemail.com"
sub = "Your alarm has been triggered!"
body = "The " + sensor + " sensor was tripped. You should assess the situation!"
head = "AN URGANT MESSAGE FROM YOUR RASPBERRY PI"
msg = head + "\n\n" + body + "\n\n\n"

try:
smtpserver.sendmail("rpi.alert.infor@gmail.com", "rabostock92@googlemail.com", msg)
smtpserver.close()
except (smtplib.SMTPException), e:
print e
smtpserver.close() 

Finally I will just post the whole Python script:
import time
import webiopi
import smtplib
import socket
import sys
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)

#LED
GPIO.setup(16, GPIO.OUT)
#Button
GPIO.setup(11, GPIO.IN)
#Reed
GPIO.setup(13, GPIO.IN)
#Buzzer
GPIO.setup(12, GPIO.OUT)
#Motion
GPIO.setup(15, GPIO.IN)

#Variables
armed = False
alert = False

#Functions
def sendEmail(sensor):
try:
smtpserver = smtplib.SMTP('smtp.gmail.com', 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo()
try:
smtpserver.login("rpi.alert.infor@gmail.com", "PASSWORD HERE")
except (smtplib.SMTPException), e:
print e
smtpserver.close()
except (socket.gaierror, socket.error, socket.herror, smtplib.SMTPException), e:
print e

sub = "Your alarm has been triggered!"
body = "The " + sensor + " sensor was tripped. You should assess the situation!"
head = "AN URGANT MESSAGE FROM YOUR RASPBERRY PI"
msg = head + "\n\n" + body + "\n\n\n"
try:
smtpserver.close()
except (smtplib.SMTPException), e:
print e
smtpserver.close()

def configurePinStatus():
GPIO.output(16, False)
GPIO.output(12, False)

def waitForButtonPress():
print "Press the button to arm me. I will give you 10 seconds to leave the room."
while GPIO.input(11): #Will be true when no button is pressed because we are using a pull up resistor
time.sleep(.2)
return True

def armToggle(t):
global armed
if t == True:
armed = True
GPIO.output(16, True)
else:
armed = False
GPIO.output(16, False)

def armedCountDown():
for i in range(0, 10):
GPIO.output(12, True)
time.sleep(.5)
GPIO.output(12, False)
time.sleep(.5)

def alertAlarm():
print "\nAlert!"
global alert
alert = True
GPIO.output(12, True)
armToggle(False)

def stopAlarm():
global alert
alert = False
GPIO.output(12, False)

def checkDoor():
if GPIO.input(13):
print "\nThe door sensor was triggered!"
sendEmail("Door")
alertAlarm()

def checkMotion():
if GPIO.input(15):
print "\nMotion was detected"
sendEmail("Motion")
alertAlarm()

def checkDisarm():
if not GPIO.input(11):
armToggle(False)
time.sleep(.25)
print "The system has been disarmed"
time.sleep(.5) #Need to slow the system down so that it doesn't arm the system again whilst the user presses the button

def arm():
armedCountDown()
armToggle(True)

def disarm():
stopAlarm()
armToggle(False)

server = webiopi.Server(port=9898)
server.addMacro(arm)
server.addMacro(disarm)

configurePinStatus()
print "*********************************************************************************************************"
print "*                                                                                                       *"
print "* I was intended for a headless Raspberry Pi. Please use the hardware to interface with me. *"
print "*                                                                                                       *"
print "*********************************************************************************************************"

def loop():
if armed:
checkDoor()
checkMotion()

webiopi.runLoop(loop)
server.stop() 
There is a lot more to the system than I have explained but I wanted to keep it a shortish post. Any thanks!

Tuesday, 11 June 2013

My first Robot! An Ongoing Project - 1

It has been an ambition of mine to make a small programmable robot for a while now and I have finally got the time since I left University. The requirement of the robot was to be purely hack-able. That means that it all has to be solderless so that I can swap and remove things easily and re-program it to do something else. So far the chassis is made of foam core. It can be picked up from Hobbycraft for £3.99 for an A3 sheet. The Motors are 6v-12v DC from Maplins (more on this later), and the wheels where cut from MDF wood using a circular saw drill bit (I don't know the proper name!). A solderless breadboard was a 'must have' for a hack-able robot which is stuck down to the center of the chassis. For the brains of the robot I chose to use a Arduino Uno, mainly because its small and I can take out the ATMega chip and put it into the bread board to save weight if I need to as I plan on addding a Raspberry Pi for networking type things. The Arduino runs off of 9v, so I am experimenting with a 9v battery for now but I am aware that 9vs worth of AA batteries would probably last longer. 

Now for the problems! Due to the fact that I have no experience with robotics or motors, I did not realised (stupidly) that gear-less DC motors have no torque what-so-ever. Even more annoyingly, you cannot buy gears for them; well at least I couldn't find any on the internet. You would have to buy motors WITH gears already on them. However, it was more economical to just buy continuous rotation servos which have plenty of torque to get my robot moving. 

I will post an update when I finally get my robot moving. I will be posting Arduino sketches and possible schematics for the robot. However, programming is my real domain so I wouldn't really want anyone to copy my circuits in case they're wrong, so I might not! I would much rather people comment and tell me how I can improve the circuit.

Monday, 10 June 2013

Three Ways of Multi Threading for Java/Android and Thread Communication

Multi threading in Android apps is a fundamental aspect, especially for larger apps. This is because it's not the best idea to have your whole app running on the main UI thread as it can become overloaded and become slow. Plus, unlike helper threads, stopping the main UI thread will cause the app to crash. For these reasons I have felt that it was important to address this. Now for most scenarios, using an Async task should do the job just nicely. However, these are really only designed for short tasks.

I wanted to gather a greater knowledge of opening new threads in my apps, so I decided to explore some possibilities and make a small app that would use a few different ways to open a new thread. There is also the very annoying fact that you cannot update the UI from a helper thread so I had to find a way to communicate with my main UI thread. You can do this by using a handy class in the Android API called 'Handler'. A Handler object allows you to send messages to it from another thread using the 'Message' class. You will need to make sure that the thread has access to the Handler object by passing it in the constructor etc.

The app I made opened up a thread in three different ways. The first way (t1 in the app screenshot) was via a class I made that implemented 'Runnable'. This is a pretty standard way in Java programming and is not special to Android (nor are any of the other methods apart from the handler... that is part of the API). This way allows you to define other characteristics and methods for that object alone and have each instance of the object and its behaviours run in a separate thread. The second way (t2 in the app screenshot) is done by making a new Thread object locally in the activity class as part of a method. This way allows you to code different behaviours that an object may have that all need to run in a separate thread. The last way of threading (t3 in the app screenshot) I decided to use a 'TimerTask'. In my code I made a nested class that extended the 'TimerTask' class. This class then had to implement a run function just like if you implemented 'Runnable'. The only difference is that when you come to run the thread you need to make a 'Timer' object and pass an instance of the 'TimerTask' you just made following with some more scheduling information. You can make this kind of thread execute an infinite amount of times or for a number of times. You can also set the frequency at which the thread re-executes. These types of threads would be good for a game loop, or some other type of task that needs to be scheduled and repeated.

The code is as follows:
public class MainActivity extends Activity {
      private TextView tv;

      @Override
      protected void onCreate(Bundle savedInstanceState) {      
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv = (TextView) this.findViewById(R.id.text_view1);

            //Thread from another class (talking to this class)
            Task1 t1 = new Task1(handler);
            new Thread(t1).start();

            //Thread from within a method
            //pretty much the same behaviour as the previous but coded in a different manner
            Task2();

            //From a Timer thread
            Timer timer = new Timer();
            Task3 t3 = new Task3();
            timer.schedule(t3, 0, 3000);
      }

      private void Task2 (){
            new Thread (new Runnable() {
                  @Override
                  public void run() {
                        for (int i = 0; i < 5; i++) {
                              String num = "t2";
                              //send a message
                              Message message = Message.obtain();
                              message.obj = num;
                              handler.sendMessage(message);
                              try {
                                    //Notice how I am able to stop the thread
                                    Thread.currentThread().sleep(1000);
                              } catch (InterruptedException e) {
                                    e.printStackTrace();
                              }
                        }
                  }
            }).start();
      }

      private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message message){
                  //this is were the messages get sent to
                  tv.setText(tv.getText() + "\n" + message.obj.toString());
            }
      };

      private class Task3 extends TimerTask {
            @Override
            public void run() {
                  String num = "t3";
                  //send a message
                  Message message = Message.obtain();
                  message.obj = num;
                  handler.sendMessage(message);
            }
      }
}

public class Task1 implements Runnable{
      private Handler messageHandler;

      public Task1 (Handler handler) {
            this.messageHandler = handler;
      }

      @Override
      public void run() {
            for (int i = 0; i < 5; i++) {
                  String num = "t1";
                  //send a message
                  Message message = Message.obtain();
                  message.obj = num;
                  messageHandler.sendMessage(message);
                  try {
                        //Notice how I am able to stop the thread
                        Thread.currentThread().sleep(1000);
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  }
            }
      }
}