Advanced Tutorial

Starting the server

Before you can use the GPIO pins, you must start the GPIO server. There are several ways to do this:

  • Choose Start GPIO server from the Edit menu to turn it on. If the server is already running, then Stop GPIO server will turn it off.
  • A Scratch broadcast of gpioserveron or gpioserveroff will have the same effects.
  • Projects saved when the GPIO server is running will have that status recorded and, on loading, will try to start the server if it is enabled.
  • You can also set an option in the scratch INI file. See the Appendix below.

Basic GPIO usage

Without any further setup, you now have access to the basics of the GPIO system. This currently uses the broadcast blocks to send commands to the GPIO server just like the original mesh network-based broadcast messages.

For instance, to configure GPIO pin 4 as an output and turn it on, you create the two following broadcasts:

broadcast config4 out gpio4on

As always, you can assemble this text with normal join, pick, or list-handling blocks. For example, if foo = 17, then

broadcast join gpio join foo 17

would broadcast gpio17on and thus set the GPIO pin number 17 (under the BCM numbering - not the physical or wiringPi numbers!) to on.

The pins need configuring before you can use them to do anything. We can set the direction of the pin (in or out) and, for input pins, the pull-up mode (up, down, none).

  • For input pins we can use 'in' or 'input'. Both of these are treated the same as 'inpullup' or 'inputpullup' and default to setting the pull-up resistor to pull up the signal.
    • To set the pull-up resistor to pull the signal down, we use 'inpulldown' or 'inputpulldown'
    • We can set the pull-up resistor to float with 'inpullnone' or 'inputpullnone'
  • Output pins are configured simply by 'out' or 'output'
  • Output with PWM, which is useful to make LEDs glow part-bright or to make motors run with variable speed etc., is configured with 'outputpwm'

For example:
broadcast config 11 inpulldown

Pins set to be inputs are connected to the Scratch sensor variable system, and so they appear in the list of possible values in the sensor blocks:

sensor block gpio11

and can be used in the same manner:

if gpio11 sensor value

You won't find your input pin in the list until after running your config broadcast. Until then, the GPIO server can't know that you want it to be an input. When you save your project, the input will still be hooked up.

With these very simple commands, you can build fairly complex GPIO-handling scripts to read buttons and operate LEDs, motors, and so on. We also have commands to return the time, return the machine IP address, read various temperatures, read an ultrasonic distance sensor, fetch a weather report, and even take a photo with an attached Raspberry Pi Camera Module and set it as the current costume.

This script (provided in the Sensors and Motors folder as Sensors and Motors/gpio-demo) illustrates most of the above :

gpio-demo script

Along with a suitably configured breadboard, it provides the ability to turn LEDs on and off with the press of a button, to take a photo with a countdown provided by a progressively brightening LED, ways to check the time, and so on.


Note that we can have a single broadcast that includes several messages, such as gpio24on gpio18pwm400 in the script above.

Basic GPIO commands

In the command listings below, we use
[comm] + pin number + [ on | off]
to indicate a command of the form comm17off or comm7on.
For a variable
led + light number (1..5) = ( 0 .. 100)
indicates a variable named led5 may have a value from 0 to 100. Likewise,
foo = ( 1 | 4 | 7 )
indicates the variable foo may be set to 1, 4 or 7.

Simple GPIO control

The basic GPIO command list of things you can do without any HATs plugged into your Pi is as follows:

  • config + pin number +

    • in, input, inpullup or inputpullup to set as input with pull-up
    • inpulldown or inputpulldown
    • inpullnone or inputpullnone
    • out or output to set as digital output
    • outputpwm to set as a PWM pin

    For example, config12in to set pin 12 as an input with the default pull-up and add a sensor variable gpio12.

  • gpio + pin number + [ on | high | off | low ] to turn an output on or off For example, gpio17on to turn on pin 17.

  • gpio + pin number + pwm + [ 0..1024 ] to use the PWM output

    For example, gpio22pwm522 to set the PWM duty cycle to 522 out of 1024, or roughly half power. Note that many LEDs don't appear to change their brightness in a simple linear manner, so 522 might be barely glowing or nearly full brightness.

Servo driving

  • servo + pin number + [percent | %] + [-100...100] to move a connected servo to position.

    For example servo15%0 to position a servo in the centre of its range.

  • servo stop to turn off the servo driver.

In the Servos and Motors/gpio-servoDemo script, you can see how to move a servo or connect it to a variable like the position of a sprite. You will need to wire your servo up like this:

gpio servo wiring layout

Ultrasonic sensor

  • ultrasonic + trigger + trigger pin + echo + echo pin to connect a typical SR04 ultrasonic sensor
  • ultrasonic stop to turn off the sensor support at the end of your script

Here is an example wiring layout using pin 16 as the trigger and 26 as the echo:

gpio ultrasonic wiring layout

If you use this wiring setup with the script in Sensors and Motors/gpio-ultrasonicDemo, you will see how to read the distance and move a sprite accordingly. The other ultrasonic demo in Sensor and Motors/gpio-ultrasonicIntruderAlarm requires a Camera Module, and will take a snapshot when anyone gets too close.

Weather reports

  • getweather + city name + , + country two-letter code + , + your user key from [OpenWeatherMaps]( will create sensor variables for the named city's temperature, wind speed and direction, rainfall, and cloud cover. You must sign up to get a key from them (free accounts are available). See OpenWeatherMaps for details.

For example

getweather Rio de Janeiro, BR, 1234EF65B42DEAD

would make the sensor variables

Rain in Rio de Janeiro
Temp in Rio de Janeir0

...and so on. The commas between the city name and country code and your key are vital to let the GPIO server know where to split things. Some cities have simple names like 'Ee' or 'Manchester' whilst others get a bit more involved like 'Sault Ste Marie' or 'Llanfair­pwllgwyngyll­gogery­chwyrn­drobwll­llan­tysilio­gogo­goch'. Note that the OpenWeatherMaps server doesn't know every city in every country, nor does it have every kind of weather data for all those it does know, so sometimes you will get no useful information.

The script Sensors and Motors/gpio-citytemperaturegraph shows how to get the weather data for London and plot the temperature. Since weather data doesn't normally change rapidly we only fetch the data every 15 minutes in order to not overload the website.

Reading temperatures

  • gettemp connects to a couple of possible temperature sensors.

    • gettemp + cpu reads the cpu temperature and creates a sensor variable cputtemp. For example: gettempcpu. An example project that plots a graph of the CPU temperature can be found in the Sensors and Motors/gpio-cputtemperaturegraph project.
    • gettemp on its own will try to find an attached 1-wire DS18B20 thermal sensor and creates a sensor variable named temp + [the twelve-digit sensor ID].
    • gettemp + [a previously discovered twelve-digit 1-wire id] will directly connect to that identified DS18B20 sensor if possible.

      Note that 1-wire sensors take about half a second to read, so reading the sensor frequently may make Scratch appear to get very slow.


  • photo uses the camera to take a photo and insert it as the current costume of the sprite (or stage if that is selected).
  • photo + [big/large]: a 'big' photo is the same size as the stage. For example: photobig or photo large.
  • photo + [width @ height] takes a photo size width by height pixels, up to the limits of the camera. You can try almost any reasonable number for the width and height but remember that very small numbers (under 32 or so) don't necessarily produce a proper image and very large numbers can make an image so big it seems to crash Scratch. For example, photo800@600 will normally be acceptable but photo2000@1600 may cause problems.


  • gettime adds some time values to the sensor variables, specifically the hours value, the minutes value, and the full date and time as YYMMDDhhmmss.
  • getip adds a sensor variable for the machine's local host address IP number.

Appendix: enabling and disabling the GPIO server

In normal use you shouldn't need to enable the GPIO server, as by default it is enabled but stopped. We can change this by adding a line to the init file. In the Home directory we can have a file named .scratch.ini - the initial dot is important to make it a hidden Unix file. Simply add the line gpioserver=X to the file, where X is:

  • 0 - to disable the GPIO server, preventing users or loaded projects from using it
  • 1 - to enable the GPIO server but leave it turned off, which is the default when there is no .scratch.ini file
  • 2 - to both enable and start the server, which might perhaps be useful in a classroom when the lesson will be about GPIO use

Note that the older mesh/network server setup is currently semi-hidden under the Share menu: you have to hold down the shift key whilst opening that menu. It works exactly as before and still connects to external socket-based servers.


Published by Raspberry Pi Foundation under a Creative Commons license.
View project & license on GitHub