Introduction: Physical Computing - Scratch for Raspberry Pi
This Instructable is competing on contest: "Explore Science", If you like it, please give your vote by clicking at the above banner. Thanks a lot! ;-)
This is my second tutorial with a focus on Scratch and Physical Computing. A few days ago, I published: Physical Computing - Scratch for Arduino, where as the name says, I explored how to use Scratch and Arduino to interact with the physical world. On this new one, we will do the same, but be exploring the Raspberry Pi.
I also invite you to see my 3rd tutorial about Scratch: Physical Computing - Scratch 2.0 for Raspberry Pi
As we know, Scratch is a great tool to teach beginners how to code, but before starting our tutorial, I really recommend that you go to Scratch Website and familiarize yourself with the language, following some basic tutorials. Doing that will help you to better understand how to use a Raspberry Pi for Physical Computing.
But, what is Scratch?
With Scratch, you can program your own interactive stories, games, and animations — and share your creations with others in the online community. Scratch helps young people learn to think creatively, reason systematically, and work collaboratively — essential skills for life in the 21st century. Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab. It is provided free of charge.
... and not only learn how to program interactive stories but also do Physical Computing:
According Wikipedia, Physical computing means building interactive physical systems by the use of software and hardware that can sense and respond to the analog world. While this definition is broad enough to encompass systems such as smart automotive traffic control systems or factory automation processes, it is not commonly used to describe them. In a broader sense, physical computing is a creative framework for understanding human beings' relationship to the digital world. In practical use, the term most often describes handmade art, design or DIY hobby projects that use sensors and microcontrollers to translate analog input to a software system, and/or control electro-mechanical devices such as motors, servos, lighting or other hardware.
Physical Computing intersects the range of activities often referred to in academia and industry as electrical engineering, mechatronics, robotics, computer science, and especially embedded development.
Cool! Now that we know what is the Scratch and what is Physical Computing, the next step is to learn is how to use this fantastic visual language to command a Raspberry Pi and so, interact with our physical world!
In short, we will learn in this tutorial how to:
- Read digital inputs as buttons
- Generate digital outputs, turning ON/OFF LEDs and play sounds with a buzzer
- Create animations on your screen that will interact with our LEDs, buttons, and buzzer.
The above electrical diagram shows all the devices that will be connected to our Raspberry. But do not worry, we will go step by step installing and programming each of those components.
Here, you can see a short video with one of the examples to be developed during this tutorial:
Step 1: BoM - Bill of Material
- Raspberry Pi (V2 or V3)
- LEDs (Red, Yellow, and Green)
- 1 Button
- 1 Active Buzzer
- Resistors: 3 x 220 ohm
- Cables
- Full Breadboard
Step 2: The Raspberry Pi
We will not cover how to prepare the Raspberry Pi to be used in this tutorial, but If you need any help, please refer to this link: Installing Raspbian with NOOBS.
Our Raspberry Pi will be running with the last Raspbian version of the Operational System, having PIXEL, as our desktop environment.
Once we will interact with the physical world it is good to remember that our gateway to that will be the Raspberry Pi GPIO connector. The above photo shows the connector, where I have drawn some fictional components in red.
Pin Numbering
Important to mention that we will use Broadcom (BCM) pin numbering for the GPIO pins, as opposed to physical (BOARD) numbering. Any pin marked “GPIO” in the above diagram can be used as a pin number. For example, if a LED was attached to “GPIO13” (physical pin 33) you would specify the pin number as 13 and not "33".
Step 3: The Scratch
As I comment at introduction, it's good that you became familiar with the Scratch language. There are 2 ways to do that:
- Go to Scratch Official Website, where you learn Scratch 2.0 or
- Go to Official Raspberry Foundation site, where you can learn the specific version that will be used here in this tutorial (V 1.4).
A new offline Scratch 2 version started to be delivered bundled with the last Raspbian OS release. It is really great, BUT at least with me, it also introduced some "freezing issues". Due to that, I wrote this tutorial using the Scratch 1.4 (that is also delivered together with Raspbian).
But, if you are interested, I also wrote another tutorial, using Scratch 2.0. Anyway, I suggest that you first be familiar with this version and after, take a look at the 2.0 tutorial.
When you have the Pixel desktop in front of you, go to left up corner Application Menu (the "Raspberry Pi logo") and open it. You will find as one of the options: "Programming". Open it and click on "Scratch".
Once you open the Scratch program, you will get the below screen:
Step 4: Digital Output - Playing With a LED
Let's start connecting a LED to GPIO 13 of our Raspsberry Pi (RPi, for short).
The most import Scratch block to be used with RPi is the "broadcast [ ]", that you find on "Control menu" (yellow blocks).
The first thing to do after you started a program is to "broadcast" that you need activate the GPIO functionality. You can do it "broadcasting" the command: "gpioserveron" as shown below:
- broadcast [gpioserveron]
Next, you need to instruct the RPi that that specific pin, the GPIO13 will be an output, using "config13out":
- broadcast [confi13out]
At this point, if you connect the above blocks with the starting block (Green flag), the RPi will be ready to receive commands regarding its GPIO.
For starting, drag 2 new "broadcast[ ]" blocks to the SCRIPTS AREA, as shown in above picture:
- broadcast [gpio13on]
- broadcast [gpio13off]
Clicking on those blocks you will turn ON and OFF the LED
That's it! You are now controlling the world! Be smart and responsible!
You can download the code here: LED.sb
Step 5: Blinking a LED
Now, let's create a real blink code using Scratch.
- Start your program when the "Green Flag" is clicked, for that you will need the block:
- When "green flag" clicked (it is the first block in the Control menu - "Yellow")
- Drag the loop block "Forever"
- Inside the loop Forever, put the blocks that you used on the last step.
- if you run your code, you will see that nothing happens, or better, the LED will be ON and OFF so quickly that you will not realize it. So, you must add some delay, let's say 1 second after each block.
And that's it!
The screenshot above will show you the final program and bellow a video with our LED blinking:
Try some changes, explore the code!
Good luck!
Step 6: Adding More LEDs
Now, that we know how to control one LED, let's install 2 new ones, with different colors:
- RED
- YELLOW
- GREEN
Repeat what you did at last step, connecting the LEDs as shown above:
- RED ==> GPIO 13
- YELLOW ==> GPIO 19
- GREEN ==> GPIO 26
You must start with the green flag, following by the bellow broadcasts[ ] blocks connected:
- Activating the GPIOs using:
- broadcast[gpioserveron]
- Config the GPIOs as outputs using:
- broadcast[config13out]
- broadcast[config16out]
- broadcast[config26out]
And now you can turn ON and OFF those LEDs individually using the blocks, leaving them not connected:
- broadcast [gpio13on]
- broadcast [gpio13off]
- broadcast [gpio16on]
- broadcast [gpio16off]
- broadcast [gpio26on]
- broadcast [gpio26off]
Play a little with those blocks, trying to create something interesting exploring other blocks.
The code for my example is here: 3LED.sb
Step 7: An Automatic Traffic Light
Let's create something useful here. Once we have 3 LEDs and by coincidence a RED, a YELLOW and a GREEN, how about to create an automatic traffic light?
Sure! let's do it!
First, we will create a set of blocks, that will be our "configuration function". Is the set of blocks to the left on above picture. We will do 3 tasks with it:
- Activate the GPIOs
- Define the correspondents GPIOs as output
- Set all LEDs as OFF
Take a look at it.
To create a "Traffic Light function" (the right set of blocks), we will follow the below flow, as you can see on streets (of course there, the lights worked longer in seconds):
- RED light during 3 seconds
- Yellow Lights during 1 second
- GREEN Light during 3 seconds
- return to RED Light and so on...
Translating to our electronic world:
- Turn On RED LED (GPIO 13 on)
- Wait 3 second
- Turn Off RED LED (GPIO 13 off)
- Turn On YELLOW LED (GPIO 19 on)
- Wait 1 second
- Turn Off YELLOW LED (GPIO 19 off)
- Turn On GREEN LED (GPIO 26 on)
- Wait 3 second
- Turn Off GREEN LED (GPIO 26 off)
- Turn On RED LED ..... and so on
If we want this program running forever as a real traffic light found on a city street, let's put the above blocks inside a "FOREVER Loop", the same way we did on the Blink code.
The above screenshot will show you the final program and bellow a video with our LEDs working:
The final code could be also downloaded from my GitHub: Auto_traffic_light.sb
Step 8: Interacting With Physical World Using Animation
A very cool experience is to mix the great potential of Scratch creating animations on our computer screen (will appear at "stage area") and the possibility of physical interaction using the Raspberry Pi.
As a first project, we will create a "virtual" Traffic Light inside the Stage that will change the lamp color, following the LEDs sequence.
How can we do it?
- Let's create 3 new backgrounds and name them: "red", "yellow" and "green". Those backgrounds are shown on the first screenshot above.
- What I did was to "import" one "blank traffic light", from the internet, "copy" it 2 times and use the editor to fill with color each one of the lamps.
- At "Scripts" Tab besides "Backgrounds" (second screenshot above), I used the control block "when I receive something to do something", to change to those backgrounds. For example:
- when I receive [red]
- switch to background [red]
- At previous code, before we call the wait [ ] block, we will call a new broadcast [ ] block, calling that specific background, for example:
- broadcast [red]
The above 3rd screenshot will show you the final program and bellow a video with our Interactive Automatic Trafic Light working:
The final code could be also downloaded from my GitHub: Auto_traffic_light.sb
Step 9: Digital Input Using a Push-Button
Up to this point, our Raspberry Pi was "activating" devices using the GPIOs as outputs, but an important task when we are talking about physical computing is the ability of "sensing" the world. So, what we will do now, is to set-up our GPIOs as an input mode.
Let's begin with connecting a push-button to GPIO 21. Follow the above diagrams and make the proper connections. Note that by default, we will be using the internal "Pull-up" resistor, what means that if you leave a GPIO (programmed as an input) "open", the RPi will interpret it as a logic level "1". Pressing the push-button, we will put a "0" logic level at that GPIO.
So, same as we did before, we must define this GPIO, but now as an input:
- broadcast [config21in]
The important new block introduced here, found at Sensing menu (the "light blue"one) is:
- [gpio21] sensor value:
This block has several possible parameters: [sound], [light], [slider], etc.
This block will return "1" if on GPIO we have a logical level "1" (push-button not pressed) and "0" if we have a logical level "0" (push-button pressed).
You should now see the current state of the pin in the stage area:
- gpio21 sensor value [1]
Pressing the push-button it will be changed to:
- gpio21 sensor value [0]
Also, note that we have 2 blocks of code that will run in parallel (the set of blocks that starts with the green flag)
- One at the top, that will setup our GPIOs
- Another at the bottom, that will constantly check up the GPIO state, sending a "0" to GPIO 13 (RED LED) if the push-button is not pressed and "1" if pressed and so, turning on the Red LED.
Below the correspondent code:
Step 10: Introducing Variables
Now, let's start to introduce a new type of block, a "variable" (the "orange blocks").
We will create a variable naming it: "buttonPressed", by clicking on "Make a variable" inside "Variables Menu" (the orange one). Doing that, 4 new blocks will be created, related to that variable:
- set [buttonPressed] to <0>
- change [buttonPressed] by <1>
- show variable [buttonPressed]
- hide variable [buttonPressed]
Also, note in the above screenshot that we have now 3 blocks of code that will run in parallel:
- One group at the top, that will setup our GPIOs
- One group that will constantly check the push-button condition, setting the "buttonPressed" variable depending on push-button condition (note that we are working now with a "reverse logic" when we compare with the previous example):
- "True" if pressed
- "False" if not pressed
- Another group that will set up the GPIO13, depending on the value of our "buttonPressed" variable.
- The Red LED will TURN ON now if the push button is PRESSED.
The changed code can be found here: LED_Button_V2.sb
Step 11: Push-Button With "Memory State"
Let's change the previous code, so we can have the state of RED LED changed each time that the button is pressed.
We say that the RED LED state will be "toggled" or better, if its state was previously "ON", it will be changed to "OFF" and vice-versa. For that, we will change the block created on the last step:
- When we check the GPIO 21, we will verify first the current state of the variable "buttonPressed", giving it an opposite state.
There are several different ways to do that, for example defining 2 different variables, one for current state and another for the previous state. You can try it.
Note that a small delay is introduced each time that the push-button changes its state. This is due to the fact that we need "to debounce" the state of the push-button.
You can download the code here:
Step 12: Exercise: Push-Button and 2 LEDs
Let's put together the previous 2 codes and create a program that will perform as explained below:
- If the push-button is pressed, RED LED will be "toggled"
- If the push-button is pressed, GREEN LED will follow its state.
Before you look at the code, try it by yourself.
After that, you can check my version here:
Step 13: Exercise: Push-Button and 3 LEDs
Congratulations! You are a Pro my friend! ;-)
Let's try now, a more complicated task:
- RED LED will follow the state of the push-button
- YELLOW LED will toggle its state each time the push-button is pressed
- GREEN LED will flash 3 times each time that the push-button will be pressed for 10 times.
Before you look at the code, try it by yourself. After that, you can check my version here: LED_Button_V5.sb
Step 14: Final Project - Traffic Light With Pedestrian Cross
Now we will start to final project on this tutorial, that will be a animation, mixed with the real world.
We will start from the Automatic Traffic Light code developed before, adding a pedestrian push-button.
So our project will work like that:
If a pedestrian DOES NOT press its push-button, the "Traffic Light function" will follow the below structure, as you saw before:
- RED light during 3 seconds
- Yellow Lights during 1 second
- GREEN Light during 3 seconds
- so on...
Translating to our electronic world:
- Turn On RED LED (GPIO 13 on)
- Wait 3 second
- Turn Off RED LED (GPIO 13 off)
- Turn On YELLOW LED (GPIO 19 on)
- Wait 1 second
- Turn Off YELLOW LED (GPIO 19 off)
- Turn On GREEN LED (GPIO 26 on)
- Wait 3 second
- Turn Off GREEN LED (GPIO 26 off)
But, if the push-button is pressed, the Traffic Light will finish its current sequence and goes to RED, staying there until the pedestrian crosses the street. We must create a "Pedestrian function" to control it.
So, let's think about this new function.
To simplify it, we will only introduce a new element here, a Sound Buzzer that will beep during a certain amount of time, enough for a pedestrian cross the street (you can easily add a couple of new LEDs exclusively for the pedestrian task). Afer that, the normal sequence should be re-established.
First, let's connect the Buzzer. As shown in above diagram, we must installed it on GPIO 16, which one must be defined an "output" (so, you must append a new block at set-up group of blocks).
We will program the buzzer as a beeper, the concept is the same as we saw with the Blink code.
So, in short, our code will:
- Run the sequence RED-YELLOW-GREEN automatically until the button is pressed:
- Variable buttonPressed must change from "False" to "True".
- When the push-button is pressed, a broadcast block must be sent to activate the "beep" sequence (10 times on/off for 400ms each time).
- At the end, the Beep sequence (or "pedestrian function") must "liberate" the normal RED-YELLOW-GREEN sequence, changing:
- Variable buttonPressed to "False".
The above screenshot will show you the final program and bellow a video with our project Part1 working:
The final code could be also downloaded from my GitHub:
Step 15: Final Project - Adding More Animation
On the last video, you saw that I simulated a robot walking in front of the vídeo, but why not do it with our little frobot (the MJRoBot) that already exists?
Very simple!
We will create a new sequence of blocks that should:
- Guarantee that our little robot will start:
- at its original position (right lower corner) and
- with its normal costume (right arm up).
- Make use of the broadcast: "beep". Remember it? It is the command for the "pedestrian function".
- So, nothing better for our little friend cross the street just when the beep starts!
I included a simple walking set of blocks, but yours can think about something more interesting!
Here the result of the above code:
and here the code for you to download: Pedestrian_light_v2.sb
Step 16: Final Project - Walking by London
Uau! We have accomplished a lot!!! ;-)
For a final and nice work, let's take our little friend, MJRoBot and show him London, the birthplace of Raspberry Pi!
General Specification regarding our project:
- Our little friend will start its journey around London, moving right to left across all stage area.
- When he touches the left border, we must change for the next London's background.
- When he reaches Abbey Road, he must stop because there is a pedestrian cross (Yes! The famous one!)
- Suppose that was installed there, a traffic light to protect tourists. The robot will ask us to press the push-button for him, so he can go across the street, same as Paul, John, George, and Ringo did years ago )but in an opposite direction ;-)
That's it!
As we did on previous examples, you must try to code it by yourself and only after comparing your code with my solution!
Enjoy it !!!
A quick video about the final project working:
My code solution here: Pedestrian_light_v3.sb
Step 17: Conclusion
As always, I hope this project can help others find their way in the exciting world of electronics, robotics, and IoT!
Please visit my GitHub for updated files:
For more projects, please visit my blog: MJRoBot.org
Saludos from the south of the world!
See you at my next instructable!
Thank you
Marcelo