Pi-Cars python GPIO handler for Scratch configuration

This details how to install and configure the Python Scratch handler for the Pi-Car and get it working with Scratch. You can download the software for doing this from the Pi-Store or buy one of our SD cards which is easier but you can use the way detailed here if you prefer.

For the video lesson view the video below

If you can’t view video the full text-based lesson follows…

You should start from the screen with the big Raspberry Pi on it. It is a good idea to start from fresh so pull the power lead out and put it back in again and wait for the prompt to appear. Type pi then raspberry for your password and startx to start the graphical screen.

Double click on the LX terminal:

Terminal window
Terminal window shown after double clicking on LX Terminal

Make sure you are in the right directory by typing:

cd /home/pi

You then need to open a text editor to copy in the information which will be the python program that will let Scratch talk with the GPIO pins to control your car. So type:

sudo nano picars.py

It is easiest if you use exactly the same wording I have used above here. This  should bring up a screen like this:

Nano
Nano on the LX Terminal on Raspberry Pi

You now need to copy in the text of the python program. Feel free to have a look at it but don’t think you have to understand it at the moment (you will be able to understand most of it by the end of your python driving lessons).

To get the program you need open the browser in your Raspberry Pi and go to this page on it (unless you are already viewing it on your Raspberry Pi!). You can open your browser by clicking on the icon as shown below:

Browser launch button
Where to click on the Raspberry Pi to launch the browser.

Visit this page on the browser by putting http://www.pi-cars.com into the address bar and navigating to this page. You now need to copy the code in the box below, but there is a particular way to do this to ensure it is going to work and the instructions for this way are included beneath the code:

#!/usr/bin/env python

""" Must be run as root - sudo python picars.py """
""" Script based on original version from Simon Walters http://cymplecy.wordpress.com/ """
""" Modified slightly when troubleshooting. Currenly only does GPIO outputs in order to simplify """

import time, RPi.GPIO as GPIO
import socket
import sys
import threading
import time
import sys
import struct
from array import *
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
GPIO.output(7,0)
GPIO.output(11,0)
GPIO.output(12,0)
GPIO.output(13,0)
GPIO.output(15,0)

PORT = 42001
DEFAULT_HOST = '127.0.0.1'
#HOST = askstring('Scratch Connector', 'IP:')
BUFFER_SIZE = 240 #used to be 100
SOCKET_TIMEOUT = 1

SCRATCH_SENSOR_NAME_OUTPUT = (
'gpio-output0',
'gpio-output1',
'gpio-output2',
'gpio-output3',
'gpio-output4'
)

#Map gpio to real connector P1 Pins
GPIO_PINS = array('i',[7,11,12,13,15])
GPIO_PIN_OUTPUT = array('i')
GPIO_PIN_INPUT = array('i')
print "Output Pins are:"
for i in range(0,len(SCRATCH_SENSOR_NAME_OUTPUT)):
	print GPIO_PINS[i]
	GPIO_PIN_OUTPUT.append(GPIO_PINS[i])

def create_socket(host, port):
    while True:
        try:
            print 'Trying'
            scratch_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            scratch_sock.connect((host, port))
            break
        except socket.error:
            print "There was an error connecting to Scratch! It may not have been started yet"
            print "I am looking for Scratch at host: %s, port: %s" % (host, port)
            time.sleep(3)
            #sys.exit(1)

    return scratch_sock

def cleanup_threads(thread):
	print 'About to stop thread'
	thread.stop()
	GPIO.cleanup()
	print 'Finished cleanup'
#	for thread in threads:
#		thread.stop()
#		for thread in threads:
#			thread.join()

class ScratchListener(threading.Thread):
    def __init__(self, socket):
        threading.Thread.__init__(self)
        self.scratch_socket = socket
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

    def physical_pin_update(self, pin_index, value):
        physical_pin = GPIO_PIN_OUTPUT[pin_index]
        print 'setting GPIO %d (physical pin %d) to %d' % (pin_index,physical_pin,value)
        GPIO.output(physical_pin, value)

    def run(self):
	    while not self.stopped():
		    try:
			    data = self.scratch_socket.recv(BUFFER_SIZE)
			    dataraw = data[4:].lower()
			    print 'Length: %d, Data: %s' % (len(dataraw), dataraw)
			    print 'received something: %s' % dataraw
#			    time.sleep(0.2)
		    except socket.timeout:
			    print 'Socket timeout'
			    continue
		    except:
			    break
		    if 'sensor-update' in dataraw:
			    print 'Sensor update detected'
			    #check for individual port commands
			    for i in range(len(SCRATCH_SENSOR_NAME_OUTPUT)):
				     if 'gpio-output'+str(i) in dataraw:
					     print 'Found '+ 'gpio-output'+str(i)
					     outputall_pos = dataraw.find('gpio-output'+str(i))
					     sensor_value = dataraw[(outputall_pos+14):].split()
					     #print sensor_value[0]
					     self.physical_pin_update(i,int(sensor_value[0]))

if __name__ == '__main__':
    if len(sys.argv) > 1:
        host = sys.argv[1]
    else:
        host = DEFAULT_HOST

    # open the socket
    print 'Connecting...' ,
    the_socket = create_socket(host, PORT)
    print 'Connected!'

    the_socket.settimeout(SOCKET_TIMEOUT)
    listener = ScratchListener(the_socket)
    listener.start()
    print 'Starting cleaner'
    try:
	    while True:
		    time.sleep(0.5)
    except KeyboardInterrupt:
	    cleanup_threads(listener)
	    sys.exit()

To copy the code above click on the open code in new window icon – highlighted with a red circle in the diagram below:

Show code icon
How to copy code from the browser – click on the show code icon.

This will open up a separate window with just the code in it:

Code window
Code window with the code to copy. It should be done from here to preserve the formatting.

In this window you can then press CTRL followed by the A button at the same time which will select all of the code in the window. You will then need to press the CTRL button followed by the C button to copy it to the clip board.

You now need to choose the terminal window you opened earlier and copy the python code into it. To do that you can right click in the terminal window and choose paste:

Paste into Nano
Paste the code into the text editor (nano) by using CTRL V

To save the file you can just press the CTRL key followed by the X key at the same time. This will ask you if you want to save the file and make sure you choose Y.

Finally you need to type:

sudo python picars.py

This should give you an output like the below:

picars script startup
The picars script starting up and waiting for Scratch to connect.

This shows you that it is waiting for Scratch to tell it something which is what we want – Scratch is not started yet so it should be waiting. You will need to keep that terminal window so don’t shut it by clicking on the X but you can minimise it.

So with that palava over (it should be much easier when we get the apt-get repository up and running) you are now ready to fire up Scratch and talk to the Pi-Car through it.

Advertisements

About Barnaby Kent

http://www.myactionreplay.com
This entry was posted in Uncategorized and tagged , , , . Bookmark the permalink.

One Response to Pi-Cars python GPIO handler for Scratch configuration

  1. Pingback: Pi-Cars and Scratch – Driving Lesson #1 | Pi-Cars

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