Scratch controlling the GPIO on a RaspberryPi

This blog is now old hat – I’ve made a new version and much better instructions over in a new blog.

Click here


This post is intended to make it as Simple as Pi to get up and running and make your RaspberryPi control some lights and to respond to switches and sensors.

Minimum Requirements – a RaspberryPi with Raspbian installed and a working internet connection, a breadboard, some Light Emitting Diodes (LEDs), some resistors and some wire connectors. Total cost £5-£10.

How to get a Rapsberry_Pi to control the GPIO Pins from Scratch
Your RaspberryPi needs to be connected to the internet to install the software but not needed to run ScratchGPIO.

Copy the text below ( left click just before the s of sudo and drag right until all the text in the line, up to and including, as been selected) then right-click and select copy.  Open up an LX Terminal window and select Edit and the Paste that into an LX Terminal window and run it to download the installer.

sudo wget -O /boot/

and then if using Raspberry Pi as a normal user, then just type (or copy and paste as before)

sudo /boot/

but if your logging as as a different user then type

sudo /boot/ your_username

Either way will install all the necessary extra software and some simple examples.

(If you do not have internet on your Pi then,  put your SD card into a card reader and try using your browser to right-click and save the script direct to your SD card and then put it back into you Pi and run the second instruction)

Connecting Components Up
EXTREME care should be taken when connecting hardware to the GPIO pins. You can cause your Pi to die by connecting the wrong things together – only do this if your confident of your ability to follow instructions correctly 🙂
AT A MINIMUM – get a breadboard and use some female-male 0.1 leads (available from lots of online suppliers or your local Maplin shop)

Check out GPIO pin guides to make sure you know what pins are what.

Wire up Pin 1 (3.3V) to (at least) a 330ohm resistor – connect that resistor to the long lead of an LED and then connect other end of LED to Pin 6 (0V).

It should light up. If it doesn’t try reversing your LED.

Now move the lead from Pin 6 to Pin 11.

Run the special Scratch icon (Scratch GPIO) on your desktop.
(It is actually a completely normal version of Scratch, it just runs a little Python background program as well that handles communications between Scratch and the GPIO and automatically enables Scratch’s Remote Sensor Connections(RSC))

To test out control from Scratch, click on File then Open and then click on the My Projects button and select blink11 and click on OK.  Once the project opens, just click on the OK to enable Remote Sensor Connections.  To run the script just click on the Green Flag.

Your LED should now blink on for 1 second and off for 2 seconds – see trouble shooting if this doesn’t happen.

What more can I do with Scratch and the GPIO

You can control seven pins as outputs (Pins 11,12,13,15,16,18,21) and treat seven as simple inputs (7,8,10,19,22,24,26)

As you can see in the blink11 script , you can simply use a broadcast message telling Pins to go on or off (Up to 3.3V and down to 0V)

The valid messages are pin11on, pin12on, pin13on, pin15onpin16on, pin18onpin21on along with the corresponding pin11off etc messages.

You can also say allon and allloff.

And you can replace the work on with high and replace off with low if you want to talk in pure logic levels.

You can combine msgs together to make a single broadcast so to turn Pin11 and Pin13 on and all others off you can say

broadcast pin11on pin12off pin13on pin15off pin16off pin18off pin21off


broadcast alloff pin12on pin13on

to switch pins 12 and 13 on.  Alternatively you can use the pinpattern broadcast to achieve the same result e.g:

broadcast pinpattern110

This will also set just pins 12 and 13 on.

To check an input, you should go into the Sensing block and click on the word “slider” at the bottom and you’ll notice that you have pins 10,19,22,24,25,7 and pin8.  If you connect a switch to one of these pins (through a resistor don’t forget) to OV, then you can detect when the switch is open or closed.  The inputs will normally read 1 and go to 0 when they are connected (through a resistor) to ground.  Click on the checkbox next to pin7 and try it out.

Using variables instead of broadcasts

For advanced Scratchers, you can use variables instead (or as well as broadcast messages) .

For example:  create a global variable called pin11

To make pin11 go on  use

set pin11 on

To make is go off use

set pin11 off

On can be replaced with high or 1 and off can be replaced with low or 0 so that you can use whatever logic scheme you’d like.
To set all outputs on use

set allpins on

To use a “bit-pattern” to set/unset multiple outputs simultaneously use

set pinpattern 1010001

(this will set Pin 21 , Pin 16 and Pin 11 on and all the rest off)

Note – currently there is an unfortunate “bug” in Scratch in that it remembers variable states and only sends changes out.  Even when you press the Green Flag, it will not send the state of all the variables out, it will only send them when a variable changes.  I recommend setting any gpio variables to a . and then to their initial state in a Green Flag start-up script.

When GreenFlag clicked

set pin11 .
set pin11 off

Motor Control

Connecting a motor directly to a GPIO pin WILL BREAK YOUR RASPBERRY PI!!! So don’t do it!   Google about driving motors from a RaspberryPi!!!

David Ferguson supplied the diagram below which shows a very cheap way of getting 2 motors connected safely to your Raspberry Pi. The chip used is a very cheap (37 pence) one called a ULN2003.  Wire pin11 of RPi to Pin1 on ULN2003 and then RPi pin12 to ULN2003 pin2 and finally RPi Pin6 (Gnd) connects to ULN Pin8.

Then ULN2003 pin16 goes to one motor, ULN2003 pin15 goes to other motor.  The other connections on each motor are both connected to ULN Pin 9.

Finally connect a separate motor power supply (I use a 4xAA battery pack to give 6V) and CAREFULLY connect +ve to the ULN2003 Pin 9 and -ve to ULN2003 pin 8)


Once you’ve got your motor(s) SAFELY connected up, to control a motor, it is usually required to be able to not just switch it on or off but to vary its speed.

To do this in Scratch you can create 2 special variables called MotorA and MotorB and then assign these values from 0 (off) to 100(fully on)

MotorA controls pin11 and MotorB controls pin12.

e.g To make MotorA go at half speed use

set MotorA 50

To make MotorA switch off use

set MotorA 0

The motor variables can also be be used to simply vary the brightness of an LED.

Ultrasonic Sensor
Support for cheap 4pin ultrasonic sensors has been added.  To use one, connect Pin23 to the trigger or pulse input and connect the echo output (USING A 10K RESISTOR TO AVOID BROKEN PI!) to any of the input pins  (7,8,10,19,22,24 or 26).  This simple script

broadcast sonar7
wait 1

will send a pulse out on pin23 once per second and setup up a new sensor input called sonar7 that will display the distance (in cm) that the sensor detects.   (NB You need to have done at least 1 broadcast before the sonar7 sensor will show up as a valid option)

To test if the software necessary to control the GPIO is correctly installed open a LXTerminal session and type

sudo python

If this doesn’t give an error but doesn’t make a LED on Pin 11 blink then we have real problems Houston 😦

Try connecting the lead going to Pin 11 back to Pin 1 to make sure the LED lights up then just in case you have a loose connection.

131 thoughts on “Scratch controlling the GPIO on a RaspberryPi

    • Good idea – I’ll get onto it – did the software install go OK – that’s my main concern at the moment – PS updated it yesterday – now responds to allhigh and alllow and well as Pin07 and Pin 22 appearing as inputs

  1. Absolutely great job Si! 8-D
    Really clear.
    I’m thinking a whack-a-mole type game would be simple enough to get them to use the witches for input…
    3 pictures of holes in screen,
    At random a mole (or maybe more fun if it’d a picture of the teachers head) appears
    They have to press the appropriate switch on the breadboard to “whack” the “mole”
    You could display the score (in binary) using the LEDs on the breadboard. 8 points to win & move to next level.

  2. After working out that I needed to reflash my SD card with an armhf rather than armel it worked perfectly on the first attempt! Traffic lights and Pedestrian Crossing both working! Would love to have access to further pins if possible. Fantastic resource – thank you!

      • I used Broadcasts… eg Broadcast 1off
        I was thinking a more complex box traffic light junction with filter lights too, but having access to all 17 pins would allow for all future developments.
        Thanks again for such an outstanding resource!

      • I agree, more pins please! My son is rather enthusiastically building himself a ‘StarWars’ themed control panel. A rather easy 6 LED and 5 switch battle station to get him started with a 7 inch screen sitting in the middle. I’m amazed with how quickly he created a game in Scratch, but now wants to link in some hardware. Your excellent piece of work has moved my son from just playing games to wanting to make them. Thank You!

  3. Is this available as a downloadable package that can be transferred to the Pi? I have no convenient way to connect my Pi to INET at the moment. I am developing an expander board for th Pi that will provide PLC type I/O (1/2 amp 24vdc OP and IP with LED annunciation) in blocks of 8in/8out as well as an integrated power supply that will generate 5v for the Pi from any 8-24 VDC/VAC source. I havi it breadboarded currently running from the power supply of a defunct laptop. I need to control the GPIO however and there seems little available to do it.

      • I used my notebook as a connection proxy. Tx. I will give it a try to see how it goes. I have 8 high current outputs and 8 high level inputs waiting for connections…..

  4. Updated to V1.2 – Pin 13 should now work again on Revision 2 boards and the default broadcast sysntax is no to use things like pin11on and pin12off instead of using high and low although the old syntax will still work in this version. Also the gpio variable usuage can use on/off and high/low as well as 1/0 as before. If you have a revision 2 board and Pin13 doesn’t work – please lete me know 🙂

  5. Great script, I’m going to bring my Pi to my Code Club and see what the kids build.

    I want to make a “Simon says” with 4 illuminated push to make switches. How would I modify your script to enable 4 inputs instead of 2?

    • Yep – its about the lowest value you can use to ensure no harm comes to your Pi if your connecting unbuffered components such as led/lights/buzzers/switches.

      Once you want to drive things like motors – you need to use some sort of buffer – I’m using a ULN2003 at the moment to drive 2 motors on a robot – I don’t think you can buy them over the counter at maplins but there are available from places like CPC for < 50p each

      Get some higher value resistors as well – they always come in handy 🙂


  6. This is great, my two daughters and I are having I lot of fun programming and making simple circuits – learning loads at the same time. We even enabled mesh on our iMac and can send broadcasts from iMac Scratch to RaspberryPi Scratch to light our LEDs etc. cool..thank so so much for you time and effort

    The Neales – Melbourne – AU

  7. Thanks…I have it working in my classroom. I have tied the GPIO to Snap Circuits. My students are very excited to try out their own ideas.

  8. I have no luck with the download install script, could you please just provide a simple URL for where the install script resides on the internet? What I see is a block of HTML/URL/Linkification stuff on this page. Thank you for the tutorial, I look forward to giving it a try.

    • Don’t click on the link as that is what is causing you the problem 🙂 What you need to do is copy all the text starting at sudo and ending at and paste that into an LX Terminal window and run it 🙂

  9. Hallo Simon,
    I’ve just started testing with my Gertboard. Provides a great way to get LEDs flashing. Could you make your source code modifications available. As a programmer myself I would love to help out.



    • Yep- all the source is there in ./simplesi_scratch_handler – going to do an update shortly as added in code to handle an ultrasonic distance sensor – very useful for robot projects 🙂

  10. Thanks for the post, its great fun. I am a bit stuck trying to get it running in scratch. I have done something with the python I think as I can get the test going only if I run it using python3. I installed ROI.GPO 0.41a. I was not sure if I had raspian working or not when I started so added the archives to /etc/apt/sources.list file and went from there.
    Any ideas or trash the sd and start again? Seems so close I can feel the sparks trying to jump the gap lol.

    • Sounds like your not starting off from a good position 😦 The installer is meant to be run on a recent Raspbian setup (or one brought up to date) There should be no need to install RPi.GPIO as it is part of Raspbian now. The python code is of the 2.7 variety – good luck 🙂

      • Good point! Trashed the os and installed the latest – yey flashing LED from Scratch. I am still not sure what version of wheezy I had running – it came bundled from Maplin. Onwards and upwards – thanks for the help – next step conquer the world!!

  11. What ultrasonic range finder do you recommend?

    What block do you use for sonar7?
    Is it added automatically or do I have to do something manually (if so, can you explain what)?

  12. Thanks for the code, I have my rpi setup with usernames for my kids. I ran the installer as described as one of their usernames and it ran OK, but nothing showed up on the desktop, or in scratch, but I logged out and relogged in as username pi and there was everything, so I think your scripts must have the username “pi” hardcoded in them or is there a way to change the username it installs to?

  13. @Tnever – sorry – it is hardcoded for pi user 😦 I’ll try and find out what username variables are available in Linux and alter it to install properly .

    If you know what to do please just alter the installer

    #V A add in chmod
    #Version B – go back to installing deb gpio package directly
    #Version C – install sb files into /home/pi/Documents/Scratch Projects
    #Version D – create “/home/pi/Documents/Scratch Projects” if it doesn’t exist
    #Version E – change permissions on “/home/pi/Documents/Scratch Projects”
    #Version F 13Oct12 – rem out rpi.gpio as now included in Raspbian
    echo “Running Installer”
    mkdir -p /home/pi/simplesi_scratch_handler

    cp /home/pi/simplesi_scratch_handler
    cp /home/pi/simplesi_scratch_handler
    sudo chmod +x /home/pi/simplesi_scratch_handler/

    #cp python-rpi.gpio_0.3.1a-1_armhf.deb /home/pi/simplesi_scratch_handler
    #sudo dpkg -i /home/pi/simplesi_scratch_handler/python-rpi.gpio_0.3.1a-1_armhf.deb

    cp /home/pi

    cp scratchgpio.desktop /home/pi/Desktop

    mkdir -p “/home/pi/Documents/Scratch Projects”
    chown -R pi:pi “/home/pi/Documents/Scratch Projects”
    cp “/home/pi/Documents/Scratch Projects”
    cp “/home/pi/Documents/Scratch Projects”
    cp “/home/pi/Documents/Scratch Projects”

    and feed it back to me and I’ll re-publish it 🙂


  14. Thanks, I managed to manually copy over the necessary files and got it to work in another username. Regarding your script, I am no shell guru, but I do know that $HOME is a predefined variable that would work for the pathnames. The chown command in the script I am not sure how to correct. I might do a little research and see what comes up.

  15. OK, played with it a bit, it is not as easy as it seems since sudo changes things to be associated with root. There might be more elegant ways to do this, but here is a version that I got to work by passing in the username to the script as an command line argument, if you don’t pass in a username it works on pi (as it did before):

    #V A add in chmod
    #Version B – go back to installing deb gpio package directly
    #Version C – install sb files into /home/pi/Documents/Scratch Projects
    #Version D – create “/home/pi/Documents/Scratch Projects” if it doesn’t exist
    #Version E – change permissions on “/home/pi/Documents/Scratch Projects”
    #Version F 13Oct12 – rem out rpi.gpio as now included in Raspbian
    echo “Running Installer”
    if [ -z $1 ]
    USERID=`id -n -u $1`
    GROUPID=`id -n -g $1`

    mkdir -p $HDIR/simplesi_scratch_handler

    cp $HDIR/simplesi_scratch_handler
    cp $HDIR/simplesi_scratch_handler
    sudo chmod +x $HDIR/simplesi_scratch_handler/

    #cp python-rpi.gpio_0.3.1a-1_armhf.deb /home/pi/simplesi_scratch_handler
    #sudo dpkg -i /home/pi/simplesi_scratch_handler/python-rpi.gpio_0.3.1a-1_armhf.deb

    cp $HDIR

    cp scratchgpio.desktop $HDIR/Desktop

    mkdir -p “$HDIR/Documents/Scratch Projects”
    chown -R $USERID:$GROUPID “$HDIR/Documents/Scratch Projects”
    cp “$HDIR/Documents/Scratch Projects”
    cp “$HDIR/Documents/Scratch Projects”
    cp “$HDIR/Documents/Scratch Projects”

    • I also have this problem with the script.
      You should be able to replace $HDIR with ~
      Also user can be got from $USER, but not able to find the group.

      My issue is that I’ve not used self-extracting scripts like this before, so not sure how to adjust the install script.

      • Sorry, bit slow in seeing you comment
        Here is link to my installer
        If you can mod it so it works no matter what the user name is please do and send it back.

        But I do wonder why people deviate from just using the pi user? Jsut curious

      • I use a different user name to avoid fishing when on shared networks. But I think many people use multiple accounts for different family members.
        However, it does break a lot of things (not just your installer), so certainly I would advise sticking to the pi user and just changing the password.
        I will see if I can mod it to work, no problem (very useful script) – I got to the script in the end anyway.
        I hope to add some more stuff to the when I can, would be nice to add support for the RGB LED kit, if that is Ok.
        Thanks for sharing it, been keen to get GPIO working with Scratch.

      • I’ve updated the scripts to put everything in the right place (hopefully).

        Tnever was correct though, none of the usual ways work when using sudo, so I extended his method. Also put some additional checks and ensured the other scripts are generated correctly.
        Note: You will need to update your script to pass the command line value through:
        ./ $1

        Zip of files available here:
        Or contact me via my site about page if the link is removed and I’ll email the link.

      • I think I’ve done it

        [quote]Note: You will need to update your script to pass the command line value through:
        ./ $1[/quote]

        Do you mean on the blog instructions or somewhere else ??? (Bit confused 🙂 )


    • Within the script, you make a call to

      You should just need to add $1. I’ve not used self-extracting scripts like that, so I don’t know how to update that part without breaking the crc.

      Usage is as before, but you can optionally add your own username in the command (it’ll also ask you to confirm the user and tell you if the home directory is invalid). Probably not perfect way to do it, but I think it works.

      • You’ll need to update the script to have:
        ./ %1

        Default use (will work for pi users) same as before:
        sudo /boot/

        For other users (i.e. with username):
        sudo /boot/ username

        Note: Not sure if you noticed, but the script also “generates” file.

      • Gotcha this time – found it in my build scripts 🙂

        I did notice that file but I jsut ignored it – I’ll sort it out next bug fix time as long as its not interfering with things 🙂

        Thanks very much for all you eforts -I’ll send any bug reports to you 🙂


      • Heh – get it right or you’ll be sacked form the team 🙂 Changed to $1 🙂 Really appreciate the help/efforts on this one ta 🙂

      • I think I’ve realised what I’ve done – I’ve edited a file using Samba from my PC and ended up with messing things up with the PC/Linux disagreement over newlines!

      • Hi – finally nailed problem – some funny quotes had got into the script – once I replaced them with ” standard one – it worked. I have removed your extra code that asks whether the home path detected is OK because I want the install to be as least technical as possible and a 10 yr old with a non-Linux parent wouldn’t know whether to answers 1 or 2 🙂 But I’ve left it telling the user what is going on so that should be good enough for advanced users who’ve changed default user name 🙂

      • No problem will re-test tonight. Can do it so it only catches it if there is a problem.
        Will update the zip file i linked to with source for the images too. Have more detail to put into the lesson later.

  16. Red light works with red wire in pin 1. When I run sudo python I get an error ImportError: No module named RPi.GPIO

    Got the script and ran it twice with no errors. Hope you can help.

      • Sorry I missed this the 1st time around 😦
        In the old days, RP.GPIO wasn’t bundelled with Raspbian image so I used to include it my setup.
        All recent Raspbian releases contain it so I don;t include it anymore (to avoid version conflicts) Are you using a recent Raspbian image?

  17. This is a great project, and i am desperately trying to discover what I have done wrong, I dont see the GPIO options under the SENSING {slider sensro value] drop down after enabling remote sensor connections. Any idea what i’m doing wrong, also I dont see the SCRATCH GPIO on my desktop and I have manually run the PYTHON file and tested the GPIO17 (pin11) with the BLINK11.PY script which works.

    Any pointers as to how to get the GPIO sensor options INTO Scratch are warmly welcomed. Please talk to me like I’m an idiot as well, total newbie, albeit I’ve had mild GPIO with PYTHON success.

      • I’ve tried
        when space pressed
        broadcast allon
        wait 1sec
        broadcast alloff
        wait 2secs

        But alas my LED still wont light 😦
        I’m just worried that I had read that the sensor value list should contain the GPIO numbers, but mine doesnt.

        I wondered if there was a specific Scratch package to run to include the GPIO functionality.


  18. Oh, if you not running the GPIO version of scratch (see above) you can still enable it by shift-right click on the sensor icon and clicking ‘Enable remote sensor connections’

    • Barnaby thanks for getting back to me. I’d already spotted the option to enable remote sensor, and this is in fact enabled, I’m just not getting any response from scratch to GPIO, PYTHON to GPIO is working fine. I think I’m missing a bolt on for Scratch here?

      • Forgive me Craig, you need to be running the GPIO scratch, but it sounds like you have that installed anyway, to get the blink 11 working. If you are running GPIO scratch, sometimes it looses its connection and needs restarting.

      • Barnaby
        I made the blink11.PY script work fine I can’t make the scratch work though 😦
        Does need to be running?

  19. If by chance the Scratch GPIO icon doesn’t appear on the desktop, what procedure should I go through to either
    A. Recreate it manually or
    B. run relevant Python bits to make it work as expected.?

    I’m definitely short on a step, but appear to have followed it all, I’m running 1.4a I believe.

    • I think I’ve just read Trevor’s problem and realised in running as root not Pi user. Ill try that tomorrow and see if that’s where I’m going wrong.

  20. My script doesn’t currently work if your using any other user other than pi 😦 (it is desiged for people with standard setups and not for experts wandering off into root user mode:) )

    The main problem you’ll encounter is not having the Scratch GPIO desktop icons which runs the python handler and then launches scratch.

    I have been given some mods to the install script but its goign to be after Christmas before I get any time to play with the script 😦


    • Simon
      Many thanks for your reply, I was stupid not to think of this, I will retest and I’m sure succeed tomorrow, great project by the way, I’m looking forward to investigating this with our impending year 7 group.
      P.S ‘Wandering off into Root’ LOL 🙂

  21. Hi Simon,
    After cutting and pasting the following into a ssh window (running as the pi user) :

    sudo wget -O /boot/

    I get the following error:

    Connecting to (||:443… connected.
    HTTP request sent, awaiting response… 404 NOT FOUND

    Is there a problem with this command or am I missing something obvious?

  22. Nice post, Simon! This is a good introduction to working with the GPIO pins on the RPI. Also, check out my Python module for communicating with Scratch: It provides a simple API for sending and receiving broadcasts and sensor updates. You might find it useful.

    • hi, I did look at scratchpy and was very impressed when first getting started but then I got sent a copy of the original PI-Face code which already did 95% of what I needed so I used that as the basis of my handler

  23. Nice work, Just what I was looking for to control stuff in scratch. However I cannot control a stepper motor with the GPIO functions as it is too slow. If you do not put wait(0) between writes to gpios then it will not change the pin state. Put a wait(0) between gpio writes and it will slowly drive the stepper motor, and I mean paaaiinnfuly slowly. So looks something like this
    set pin pattern 0000001
    set pin pattern 0000010
    etc.. you get the picture. how can I get it to actually write the pin without adding the wait state?( Note if wait’s removed even single stepping will not activate the pin, it’s not updating at all) Or can this be added as another function? Stepper motor control is pretty much mandatory for a lot of robotics projects. Hope you can help. Note I do write code but only in C, not a linux or python guru, and this is more for my daughter to learn basic skills.

    • I ordered a stepper motor just before Christmas so when it comes (on slow boat from China unfortunately) I’ll try it out and see what the issue is.

      I might have to write a special routine to handle steppers the way I do PWM for DC motors e.g Scratch issue the Step rate and the python handler does the dirty work.

  24. Hi,
    I appear to same a similar problem to Craig above.
    I’ve installed the script 1.4a using

    sudo wget -O /boot/
    sudo /boot/

    All installs,no errors and I get the ScratchGPIO icon on my desktop.
    I wire up the circuit as shown and wire to pin 1 first (3.3V) to see if the LED comes on. Yes it does, so I know the wiring is right.
    I then change over to pin 11.
    Run the python script and that flashes the LED perfectly. So, I know the GPIO library is in place and that the wiring is correct.

    I then open ScratchGPIO and I get the dialog box with ‘Remote sensor connections enabled’ in it.
    So, I assume all is good.

    I think open again I get the message ‘Remote sensors connections enabled’ but this time the LED doesn’t flash.

    I’m rebooted the Raspberry Pi and tried changing it to Pin 12 for the circuit and the code just in case there was a problem with the circuit. I’m using a PiCobbler and have verified all pins connect.

    Any and all help much appreciated.
    I’m hoping to have something done for a Raspberry Jam on Saturday the 20th so up against it a bit.

    Also, as an aside in your post above you state the is in the /home/pi/Scratch/ folder.
    It’s actually in ‘/home/pi/Documents/Scratch Projects’

    • Did a bit more digging.
      Note: I’m running the Septmber 2012 Raspbian Image on a 256MB Raspberry Pi.

      If I run from the terminal (with or without sudo) I get an error.

      File “/home/pi/simplesi_scratch_handler/”, line 31, in
      AttributeError: ‘module’ object had no attribute ‘setwarnings’

      Not sure if it is relevant but thought I’d post.

      If I comment line 31 out so the next line executed is GPIO.cleanup()

      Then I get an error that there is no attribute ‘cleanup’

      It looks like when I run the pythons script GPIO is initialized correctly while when I run the script that calls script is not initialized correctly.

      Again, any pointers greatly appreciated.

    • Found the solution where works, but fails.

      sudo apt-get update
      sudo apt-get upgrade

      Looked like I needed to upgrade my distribution. Not sure what specifically fixed the problem..
      I went back to the September image due to problems with PulseAudio.

      • Sorry Albert – just got to look at your comments now – All I can think of is that in the Sep image you tried, the GPIO library that my python script uses was either broken or didn’t have some features in it at that time.
        Glad to know it works with the latest


    • Albert
      My issue turned out to be one of permissions, I was logged in as root, and not PI and I was using a different build to the standard Raspbian. I reverted to a vanilla image and logged in as Pi and all was well. To be honest I never really understood why it didnt work, but tried that and it did, so I didnt question it.

  25. Hi Simon,

    Thank you for such a great scratch mod to control GPIO!
    I can teach robotic to my students with a very affordable cost.

    But I have a little problem, I want to control a motor in clockwise & counter clockwise.
    The current scratch gpio that you provide only able to control the motor in 1 direction only.
    I am using L293D chip, because my friend told me it is not recommended to use ULN2003, especially with a very cheap motor (5$ china remote control car toy)

    I am using the schema from pi-motor (
    He use pin 12 & pin 16 to set in (Low/High or High/Low) to set the direction.

    Can you open the source code to the scratch gpio, so I can modify myself to fit my needs?
    Or maybe you are kind enough to add the new feature. 🙂
    pin 12 & pin 16 to motorA
    pin 11 & pin 15 to motorB

    FYI, I voluntarily teaching computer science to the orphans and street children in Indonesia.
    Here’s one of the place I teach:

    • Hi Feiry
      The source code IS the python script in simplesi_scratch_handler folder.

      Please feel free to modify it as you wish 🙂

      I haven’t had time to play with the L293D yet but since Pin11 and Pin12 are the two pins controlled by the MotorA and MotorB variables, you’ll need to change from using pins 11 and 12 for direction – I’d suggest using pins 13 and 18 as they are set to be sued as outputs (along with pins 15 and 16)

      Good Luck

      • Hi Simon,

        Sorry I had missed that folder.

        Thank you for your suggestion on the pins to use for the direction motor using L293D.
        If anybody want to play with L293D, here’s the updated phyton script:

        I added MotorDirectionA variable for pin13 & pin18, MotorDirectionB variable for pin15 & pin16.
        To drive clockwise use value between 0 to 100, To drive counter clockwise use value between -1 to -100

  26. Hi,
    To control two motors using the ULN2003 chip, if I wired everything up like in this diagram:

    would it work?

    • Looks exactly right and is the same as I use myslef (apart from you’ve got you black/red wires mixed up on your motors – I mean the diagram colours not the actual connections :))

      Am I OK to pinch it to use it in the main description please?


  27. Love this article. Very straightforward and practical. Haven’t had a chance to try these ideas out yet, but I plan to soon. Was just wondering if you (or anyone else) might have found a good connector to facilitate hooking up to the Pi I/O pins? I’m looking for something a bit more rugged than an insulated croc clip. I’ve searched on Farnell (we live in Australia) and not been able to find anything, but I am sure you used to be able to buy a short piece of wire with a 0.1mm insulated socket on the end? I suppose I could go IDC to IDC, but that seems a bit of overkill.

    • NO!!!!! (To insulated croc clip!!!!!) 🙂
      Going to end up shorting pins 🙂
      Google for “male female jumper ebay” or up market and use adafruit cobbler :0


  28. Simon,
    Your article got me into doing some Raspberry tinkering! I played around with the Python code for a while. Then I decided that Java would allow me to go on to do more things in the future.
    To test things out, I have a LED board that allows me to control 16 LEDs from an the Raspberries I2C interface. This is quite handy for tinkering as you do not have to worry about protection of the GPIO pins and you can control the LED brightness.

    I have a little project on GitHub which has all the code and instructions on how to get the LEDs working under Java. There is also code for interfacing to Scratch so you can set the brightness directly from a Scratch variable. Should be just right for some childrens projects. I intend to convert this so both GPIO and the I2C can be controlled and write some setup instructions. If anyone is interested have a look at


  29. Thanks for the updates last night for pinpattern broadcasting via twitter, perfect.
    Are all the commands broadcast and variables going through dataraw = data[4:].lower(), so they are case independent?
    I don’t need them to be, but removes another place for confusion (and could allow camel-case names or any variant (i.e. rgballon – could be RgbAllOn rather than being read as rg ballon)).
    Note: rgballon is a special command, will tweet you a link for more details later.

  30. Great work Simon.
    Have you abandoned Analogue inputs? Using the MCP3002/3008 chip (as Gertboard) its quite easy to read light/temperature/soil moisture etc. Needs 4 pins however!! Using the dedicated temp. chips uses less pins but is far less flexible. A Buggy with LDR eyes following a torch around a darkened room is a winner. Or following a white/black line of course.
    Keep up the good work.
    Have you documented the Scratch commands that go with your GPIO_handler?

    • Hi
      I’ve not abandoned them – just not high on list as RPi doesn’t have them natively,I haven’t had a need for any yet and not seen a simple circuit to do the job – if you have one and the cct is cheap and simple then it’d a great one to add 🙂
      I’ve just used 2 digital IR sensors to do line following I thought all the commands were in this article – if you find any I’ve missed let me know.
      V2 in Progress here

      • Hi Simon;
        Analog for your code……hope it doesn’t break the stepper driver.
        ADS1015 breakout board from Adafruit (or UK supplier)

        Raspi ADS1015
        SDA SDA
        SCL SLC
        3v VDD
        0v Gnd
        0v ADDR (this chooses the lowest of 4 possible addresses)

        Attach sensor between 3v A0(A1,A2,A3) Gnd.

        i2c Installation for Raspberry Pi

        Then in

        add in the top section:
        from Adafruit_ADS1x15 import ADS1x15

        in the list PIN_NUM remove 3 and 5 (these are required for SDA0 and SCL0)
        and two entries from PIN_USE.

        just before #end of broadcast check (so its easy to find!)

        if ‘analog_1’ in dataraw:
        print “received broadcast”
        sensor_name = “analog_1”
        ADS1015 = 0x00 # 12-bit ADC
        ADS_Current = ADS1015
        adc = ADS1x15(ic=ADS_Current)
        got_it = adc.readADCSingleEnded(1)
        bcast_str = ‘sensor-update “%s” %d’ % (sensor_name, got_it)
        print got_it

        #note this could be edited to use any of the 4 analog channels (adc.readADCSingleEnded(x) where x is 0,1,2,3

        From Adafruit download the ADS1015 support files.
        Place the and the in your simplesi folder.

        With you i2c hardware connected.

        Run sudo i2cdetect -y 0 for 256mb Raspi or i2cdetect -y 1 for 512mb Raspi.
        This should return an address (48 in my case)

        make sure that this address is reflected in the Adafruit files: line 132
        def __init__(self, address=0x48, ic=__IC_ADS1015, debug=False):

        self.i2c = Adafruit_I2C(address,1) change the end 1 to 0 for old Raspi boards.

        in line 35 change smbus number to suit following the notes
        self.bus = smbus.SMBus(1) or self.bus = smbus.SMBus(0)

        You can test all this works with a short python program:
        from Adafruit_ADS1x15 import ADS1x15
        from time import sleep

        ADS1015 = 0x00 # 12-bit ADC
        ADS_Current = ADS1015
        adc = ADS1x15(ic=ADS_Current)

        while True:
        result = adc.readADCSingleEnded(0)
        #change the adc.readADCSingleEnded(0) to match the channel you want to test.
        print result
        print “Channel 0 = %.3f V” % (result * 0.001)


      • “excellent thread code” 😆 I couldn’t spull thraed 2 months ago 🙂

        I think to start with, its good enough just to have it in the main input checking loop (which itself is in a thread anyway)

        I’ve ordered one from Mr Pimoroni 🙂


      • I seem to have broken something – I’ve lost my readings – all four channels are the same!
        It’s too late now to check, I need daylight to see if I’ve broken the wiring.

  31. Simon – ads1015 up and running again.
    now have a 4 channel version of the code.
    line 132 (ish) def _init(self, address=0x48,….. or whatever is returned by sudo
    line 35
    edit as documented to force bus – the test in the code does not work.
    self.bus = smbus.SMBus(1)

    make sure these two files are in the simplesi_gpio_handler folder


    under import section add
    from Adafruit_ADS1x15 import ADS1x15

    Edit PIN_NUM = array to remove pin 3 and 5

    and two numbers from PIN_USE = array remove two numbers to keep length OK.

    Before #end of Broadcast check

    if ‘analog’ in dataraw:
    for channel in (0,1,2,3):
    sensor_name = “analog_” +str(channel)
    ADS1015 = 0x00 # 12-bit ADC
    ADS_Current = ADS1015
    adc = ADS1x15(ic=ADS_Current)
    got_it = adc.readADCSingleEnded(channel)
    bcast_str = ‘sensor-update “%s” %d’ % (sensor_name, (got_it))

    This will return analog_0, analog_1, analog_2, analog_3 to Scratch when you broadcast analog.


  32. Hi,
    I know you have an updated version of this, but I was wondering if you could give me a link to the python code that you used to allow the Ultrasonic sensor to work over two pins using a 10k resistor?

    • its here in the code
      physical_pin = PIN_NUM[i]
      #print 'Pinging Pin', physical_pin
      #print PIN_USE[i]

      ti = time.time()
      # setup a array to hold 3 values and then do 3 distance calcs and store them
      #print 'sonar started'
      for k in range(3):
      #print "sonar pulse" , k
      #print physical_pin , i
      GPIO.output(physical_pin, 1) # Send Pulse high
      time.sleep(0.00001) # wait
      GPIO.output(physical_pin, 0) # bring it back low - pulse over.
      t0=time.time() # remember current time
      #PIN_USE[i] = 0 don't bother telling system

      # This while loop waits for input pin (7) to be low but with a 0.04sec timeout
      while ((GPIO.input(physical_pin)==0) and ((t1-t0) < 0.02)):
      #print 'low' , (t1-t0).microseconds
      # This while loops waits for input pin to go high to indicate pulse detection
      # with 0.04 sec timeout
      while ((GPIO.input(physical_pin)==1) and ((t2-t1) < 0.02)):
      #print 'high' , (t2-t1).microseconds
      t3=(t2-t1) # t2 contains time taken for pulse to return
      #print "total time " , t3
      distance=t3*343/2*100 # calc distance in cm
      #print distance
      tf = time.time() - ts
      distance = sorted(self.distarray)[1] # sort the array and pick middle value as best distance

      #print "total time " , tf
      #for k in range(5):
      #print distarray[k]
      #print "pulse time" , distance*58
      #print "total time in microsecs" , (tf-ti).microseconds
      # only update Scratch values if distance is 280):
      distance = 299
      if (distance < 2):
      distance = 1

      Basically set pin to output – set it high – set it back to low to produce pulse then set it to be input and wait for ping return 🙂


Leave a Reply

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

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

Google photo

You are commenting using your Google 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 )

Connecting to %s