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.

You may also like...

137 Responses

  1. Phil says:

    An example of an actual input along with the outputs would be usefull ?

    • cymplecy says:

      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

  2. Smithy says:

    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.

  3. cymplecy says:

    V1.1a Fixes the “have to run it twice to start it bug” 🙂 No – it wasn’t your poor double-clicking – it was my poor Linux script skills 🙂

  4. snowdena says:

    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!

    • cymplecy says:

      More pins!!! 🙂 What sort of Scratch projects have you got in mind? 🙂 PS – Are you using variables or broadcasts and if so which sort of broadcasts?

      • snowdena says:

        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!

      • Magpie says:

        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!

  5. Anthony Jackson says:

    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.

    • cymplecy says:

      Just put SD card back into PC and download the installer to the card – its then available in the /boot directory when its back in your RaspberryPi 🙂

      • Anthony Jackson says:

        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…..

  6. cymplecy says:

    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 🙂

  7. hitgrrl says:

    Reblogged this on Penguin Smashing and commented:
    Very cool tut on GPIO with RaspPi in Scratch.

  8. joshje says:

    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?

  9. cymplecy says:

    Ok you lot win! – customers – who needs them 🙂

  10. joshje says:

    Do you use 330 ohm resistors for every component, be it an LED or a button? Going to Maplins tomorrow to collect supplies.

    • cymplecy says:

      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 🙂


  11. cymplecy says:

    Updated version 1.3 – 8 ouputs, 7 inputs (1.3a – bug fix for inputs)

  12. Guy Neale says:

    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

  13. Tom Dubick says:

    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.

  14. bgirardot says:

    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.

    • cymplecy says:

      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 🙂

  15. sdm says:

    Which pins do I have to use for the motor-variables A and B?

  16. ms says:

    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.



  17. ms says:

    Scatch that! Just found all the Python source in the installed files. I think I will start experimenting a bit further!

    • cymplecy says:

      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 🙂

  18. Barnaby says:

    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.

    • cymplecy says:

      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 🙂

      • Barnaby says:

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

  19. cymplecy says:

    Update: Version 1.4a up with support for using a ultrasonic range finder plus small bug fixes and more robust handler code to cope better with user errors 🙂

  20. sdm says:

    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)?

  21. Tnever says:

    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?

  22. cymplecy says:

    @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 🙂


  23. Tnever says:

    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.

  24. Tnever says:

    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.

      • Managed to grab the files by breaknig into the script.
        OK, my suggested edits didn’t seem to work, but corrected the paths and it was ok.

        • cymplecy says:

          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.

          • cymplecy says:

            May you be the first person in the world to get to see my plans 🙂

      • 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.

        • cymplecy says:

          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.

        • cymplecy says:

          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 🙂


      • Ahhh…too many years of writing batch scripts….not %1 but $1 Sorry!

        • cymplecy says:

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

        • cymplecy says:

          I’ve just tried 1.6a out on a virgin image and it fails! 🙁 Says home directory does not exist – any ideas?

        • cymplecy says:

          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!

        • cymplecy says:

          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 🙂

  25. Gordon Manson says:

    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.

    • Richard says:

      Gordon – I’ve got the same problem as you describe – did you find a fix?

      • cymplecy says:

        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?

  26. Craig says:

    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.

    • Barnaby says:

      Hi Craig,
      Try allon and alloff broadcasts – I think that Scratch will not listen until the port has been ‘pinged’

      • Craig says:

        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.


  27. Barnaby says:

    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’

    • Craig says:

      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?

      • Barnaby says:

        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.

      • Craig says:

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

  28. Craig says:

    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.

    • Craig says:

      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.

  29. cymplecy says:

    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 🙁


    • Craig says:

      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 🙂

  30. Neil says:

    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?

  31. pilliq says:

    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.

    • cymplecy says:

      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

  32. raspberry poo says:

    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.

    • cymplecy says:

      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.

  33. 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.

      • cymplecy says:

        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


    • Craig says:

      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.

  34. Feiry says:

    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:

    • cymplecy says:

      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

  35. David Ferguson says:

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

    would it work?

    • cymplecy says:

      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?


  36. David Ferguson says:

    Thanks for replying. Yes, I am fine with you using it in the description.

  37. Steve Felix says:

    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.

    • cymplecy says:

      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


  38. Michael Stevens says:

    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


  39. 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.

  40. aspro648 says:

    I totally stole both your stoplight idea and the Lego holder for our Maker Festival. I demo’ed Scratch on both Arduino and Raspberry:
    I think it made a pretty potent exhibit of programming reaching into and interacting with the real world.

  41. 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?

    • cymplecy says:

      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

      • Richard Bignell says:

        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)


        • cymplecy says:

          Great stuff 🙂 I’ll have to get one and try it out 🙂 Where did you buy yours from ?


          • Richard Bignell says:

            Adafruit 12-bit ADC

            £8 plus postage minimal soldering required.

            I’m just working on accessing all 4 channels.

            I suppose we could add it to a Thread and get a continuous stream of Analog results – not yet though, I’m cautious of touching your excellent thread code.


          • cymplecy says:

            “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 🙂


          • Richard Bignell says:

            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.

  42. krystal92586 says:

    I used your tutorial to control GPIO pins, blink an LED, and use a button on my RPi with Scratch. Thanks! For those who asked for a picture of the button, I put one in my blog at

  43. Richard Bignell says:

    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.


  44. David Ferguson says:

    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?

    • cymplecy says:

      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 🙂


  45. kerry says:

    I am a complete electronics beginner and have had some trouble with the motor circuit (I burnt up the ULN2003 and the pi wasn’t even plugged in!) Too many batteries/ the ULN the wrong way around? Do you have a breadboard diagram I can use, or some pointers?

    Sorry to be a noob!

    • cymplecy says:

      No problem – we were all noobs at one time 🙂
      As long as batteries < maximum voltage that the motors can stand then you'll be fine 4xAA normal will get a small motor turning – usually 6xAA at most

      From what you say – you just didn't identify which way round the ULN2003 was 🙁
      At one end of the chip – there is normally an indent – this marks the top of the chip and pin 1 is at top left.
      So if you follow my diagram from then on – you should be OK.

      But as you've found – get things wrong and problems will happen so you just have to be careful and double check things


  46. Brian says:

    Hi there cymplecy.
    Ive installed the scratch script and is starting to program a physical button. I havent done any soldering in 11 years so call me a we bit rusty if you want.
    The python script i used to test the button and whitch worked, looks like this.
    import RPi.GPIO as GPIO

    This will import the necessary libraries in the GPIO namespace and set the pin numbering to correspond to your breakout board.

    Now we need to set the pin as input, pin 17 is used in this example.


    Reading the pin is now as easy as:

    input = GPIO.input(17)

    If we want to print “Button Pressed” each time a button is pressed (and assuming we’ve set up the switch so the pin goes high when pressed):

    while True:
    if (GPIO.input(17)):
    print(“Button Pressed”)

    To make this script with scratch GPIO my guess is
    Broadcast set pin11 off
    something with the sensor value block, i cant actually figure out how to change this one to listen for change in pin11.
    Have any ideas? 🙂

    And great great project you have up and running here. Im looking forward to do alot of scratch physical programming with my son and in the future daughter aswell.

    • cymplecy says:

      Normally I use pin11 as an output but to use it as an input do
      On GreenFlag
      broadcast config11in
      and then press GreenFlag

      Then goto to 2nd last block in sensing section and click on the black arrow and select pin11 and then click on the checkbox to make it visible on the screen


  47. scott says:

    have you published the source code for the GPIO extensions?

  48. Simon says:

    I dont get the HC-SR04 running . It always Shows value 1.
    VCC -> 5v
    Trigger -> SCLK (Pin23)
    Echo -> Voltage devider 2200 Ohm and 2200Ohm to Pin7
    GND -> GND … Thats what i am sure is right 🙂

    Whats wrong with it?
    Took me hours up to now.

  49. Ishan says:

    Hi Simon,

    Thanks for the great documentation and instructions, it is very helpful.

    I need your help.

    System Info: I have Raspberry Pi 3B with Jessie installed.

    I am working on a Traffic Light project with kids using Scratch as the interface. I am following the Traffic Light instructions as shown on the Raspberry Pi website (

    My verbiage in this discussion refers to the Traffic Light documentation in the RPi link mentioned.

    Issue:- My LED in GPIO7 always remains on after running the script. It doesn’t turn off, despite of calling out GPIO7OFF. Even if I shut down the raspberry pi and turn it on again as soon as the raspberry pi gets powered the GPIO7 LED turns on. It seems like the GPIO7 doesn’t get “reset” or “cleaned”. I swapped GPIO7 connection with brand new GPIO11 connection but I run into the same issue there. I eventually created a python script with the keyword GPIO.cleanup() included in the script to turn the LED off.

    1. What is the call out for GPIO.cleanup() in Scratch interface? I tried using several call outs but none of those seem to work for me.
    2. Why do the raspberry Pi GPIO pins not reset when it restarts?

    Your help is really appreciated!


  50. cymplecy says:

    Please let me know which bits you found complicated as the last thing I want is an 11Year old finding that ! 🙂

  1. 13th November 2012

    […] for Scratch sensing commands and sending them to the GPIO pins. Luckily ‘SimpleSi’ had already created one which we used initially. This did seem to work pretty well but had a […]

  2. 24th January 2013

    […] Click here to read the original document. […]

  3. 25th February 2013

    […] fuera completamente portatil. Para ver como usar Scratch con Raspberry, lea el siguiente link: . Agradezco a Patricio Acevedo por este […]

  4. 10th March 2013

    […] All of this was done with a normal RPi running my Scratch GPIO package. […]

  5. 23rd March 2013

    […] With thanks to SimpleSi – […]

  6. 27th April 2013

    […] instructions that I followed are found here but they’re a little complicated for a noob like me.  So, I had to look at other pages also to […]

Leave a Reply

Your email address will not be published. Required fields are marked *