Electronic Playground With Arduino and Scratch 2 PDF
Electronic Playground With Arduino and Scratch 2 PDF
Electronic Playground With Arduino and Scratch 2 PDF
by mjrovai
This is my fourth tutorial focusing Scratch and Physical Computing. Previously, I have published here:
1. Physical Computing - Scratch 2.0 for Raspberry Pi (using the latest release of Scratch 2.0)
2. Physical Computing - Scratch for Raspberry Pi (using Scratch Version 1.4)
3. Physical Computing - Scratch for Arduino (Using S4A)
And now, we will develop new projects and ideas integrating Scratch 2.0 and Arduino, the 2 true best sellers when
we are talking about teaching electronics and code creation for children, educators, and beginners. There are few
initiatives available on the web about Scratch2 for Arduinos, being the most known the ones developed with a
focus on kits and supported by Scratch website like Lego WeDo, PicoBoard or the alternative mBlock, etc. As a
personal option, I have written this tutorial using " s2aio", a fantastic Arduino Hardware Extension for Scratch 2.0
offline editor, created by MrYsLab.
Cool! So, what we will learn here in this tutorial is how to use Scratch 2.0 to program an ARDUINO to interact with
our physical world!
The above diagram shows all the sensors and actuators connected to our Arduino. But do not worry, we will go
step by step on each component.
Here, you can see a video with a real and functional radar that you will learn how to project during this tutorial:
//www.youtube.com/embed/ZyDJsyp8UAs
1. Arduino UNO
2. LEDs (Red and Blue)
3. 1 Button
4. 1 LDR
5. 1 LM35 Temperature Sensor
6. 1 HC-SR501 - Passive infrared sensor (PIR)
7. Resistors: 2x 10Kohm and 1x 220 ohm
8. Buzzer
9. 1 HC-SR04 Ultrasonic Sensor
10. 180 Degrees 9G Micro Servo
11. Cables
12. Full Breadboard
As we know, Scratch is a great tool to teach beginners how to code, but before starting playing with Arduinos and
electronics, I really recommend that you familiarize yourself with the Scratch 2.0 language, going to the Scratch
Official Website and following some basic tutorials there. Doing that first, will help you later to better understand
how to use an Arduino on Physical Computing.
If you have worked with S4A, based on Scratch version 1.4, you should be familiarized with the basic of the
language, but the version 2.0 has great new features to enhance (and simplify) our projects, like:
To use s2aio, we will need a Scratch 2 offline Editor, go to the link and follow the instructions and install it on your
desktop. Also, download the Get Starting Guide for Scratch 2.0, so you can be familiarized with the editor.
s2aio requires Python 3.5 to work. If you do not have it, please go to Python site and follow the instructions for
proper installation.
When using s2aio, your Arduino will need be running FirmataPlus, that is a custom enhanced version of
StandardFirmata that provides support for:
Follow the normal procedure to install this library in your Arduino IDE. Once installed, go on
Examples/FirmataPlus/FirmataPlus on your Arduino IDE and open it.
s2aio installation
Now it's time for the s2aio installation. Follow below instructions carefully.
The below command will install s2aio and all of its required libraries:
For Linux and Mac users, open a terminal window and type:
Note that several "Base Scratch files", will be installed under s2aio-master directory:
/s2aio-master/s2aio/ScratchFiles/ScratchProjects
s2aio_base.sb2
Note that exist one "base" file for each supported language
Once opened, go to "More Blocks" section. You will realize that now there are several new "black blocks", which
ones we will use to control the Arduino's pins.
Note that probably you will see a red LED on top of those new blocks. This mean that the Arduino is not
connected with Scratch editor and that you must execute s2aio.
s2aio execution
An executable file will be installed on the execution path for easy startup. So, open your terminal and type:
s2aio
In my case (a Mac user). I included a "batch file" with an icon in my desktop area, so I do not to open a Terminal
any time that I want to execute s2aio.
example:
chmod +x ~/Desktop/s2aio_connect
If you want to click it to run it, add '.command' to the end of it.
eg; s2aio_connect.command
That's it. I also included an s2aio (not official) icon graphics to ease location in my desktop
So, once s2aio is running, you will realize that the LED on "More Blocks" section is now green.
In short, for initiating a new Scratch 2 project using s2aio, always follow the sequence:
That's it! The above print screen shows everything as running on my Mac desktop.
If you open a normal "new" Scratch 2 file, the arduino extentions will not be there.
Going to "More Blocks" menu, you will find the special blocks designed for Arduino. We will use 2 of them to
create our Blink function.
The first thing to do is to inform Arduino that a specific digital pin (in our case will be 13) will be [Enable] and
should work as [output]. Drag this block to code area.
Note that at same block you can select [Enable] or [disable], the digital pins number to be used and if this pin will
be an output, input, PWM, Servo, Tone and SONAR
Just clicking on this block, will enable pin 13 as an output. Now drag 2 of the Digital Write blocks:
Note that at same block you can enter the digital pins number to be used and if this pin will be setting up as a [1]
or [0].
If you click on individual blocks, you can turn on or turn off the LED, try that.
1. 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 of Control menu - Yellow)
And that's it! Below you can see the complete program:
The above screenshot shows you the final program and how I started the s2aio, this time using the Terminal.
Good luck!
What we will do from now on, will be creating one by one, specific Sprites for each one of the below electronic
components:
Each Sprite will be responsible for the initial setup of Arduino's pins and to monitor or to act accordingly with its
designated task. Also, each one of those tasks will be associated with a variable, so we will not change the Sprite
specific blocks anymore, independent of our program.
On next step, we will start with the LED and I hope the idea became more clear.
For starting, we will go to Data menu (orange) and create a new variable: "led", that will work for all Sprites (this is
very important). This variable will be set to "0" if we want the LED OFF and will set to "1" when we want the LED
ON.
Also, we will create a new Sprite going to the editor that we will name it "LED". At the editor, we will create 2
different "costumes": LED OFF and LED ON.
The LED sprite (and all the other components of our playground) will be programmed having 2 specifics group of
blocks, one for setup its initial condition and another one that will run forever (in a loop), where we will
monitor/actuate on its specific pin. The 2 groups of blocks (or "functions") are described below:
We will make a specific block named "setup" for initializing the LED
define (setup)
[Enable] Digital Pin (13) for [Output]
DigitalWrite Set Pin (13) to [0]
switch costume to [LED OFF]
set [led] to (0)
Create our "main" function, that will "call" the "setup" function
Note that at this moment, when you run the program, clicking on GREEN FLAG, nothing will happen, BUT in fact,
from now one you can set the variable led anywhere "1" or "0", that the LED will follow!
Let's create a new Sprite, that will be whom will really do all the action for us. I will be using my little friend,
MJRoBot for that. Associated with this Sprite ("MJRoBot"), we will develop our program blink never changing or
touching again the Scripts associated with LED.
On the Script area associated with MJRoBot, let's drag the blocks:
Clicking on those blocks you will see that the real LED will ON and OFF.
So, we can play with variable "led", creating a blink script as we did on the last step:
That's it!
The above screenshots show the final program and at below link, you can download the code used here:
Arduino_blink_V2.sb2
Again, try some changes, explore the code, associate the LED with animation. Install more LEDs with different
names (variables), etc!
Good luck!
Now, let's explore a new component, that will be a LED connected to one of a PWM output, writing a script a little
more complex to explore the potential of Arduino.
For starting, we will go to Data menu and create a new variable: "pwmLED", that will work for all Sprites. This
variable will be set from "0" to "255", what will make the brightness of the LED to change from minimum to a
maximum.
Let's now create a new Sprite going to the editor that we will name it "pwmLED". At the editor, we will create 6
different "costumes", simulating different LED brightness.
The Arduino UNO can provide on several of its pins, a PWM signal (Pulse Width modulation). See this link for
more details: Tutorial/PWM. In short, you can "emulate" an analog signal using a digital output.
The first thing to do is to inform Arduino that a specific pin (in our case will be 9) will be [Enable] and should work
as [PWM]. Drag this block to code area.
Just clicking on this block, will enable pin 9 as a PWM output. Now drag the Digital Write blocks:
Change the value 255 for other values. You will see that with zero, the LED will be off and with 255, the LED will
be on its maximum brightness. Try intermediate values and see what happen.
As we did with Blink, the pwmLED sprite will be programmed having 2 specifics group of blocks, one for setup and
another one that will run forever (in a loop), where we will monitor/actuate on its specific pin.
Create our "main" function, that will "call" the "setup" function and activate the pin 9 with a PWM
value and define which costume our sprite will have to simulate "brightness" on Stage (animation).
Associated with "MJRoBot" Sprite, we will develop a program (or "Script") that:
Change the PWM value from 0 to 255, returning to zero after that.
When the pwmLED (Blue LED) brightness will be at its maximum, let's turn on the led (Red LED) for
1 second.
Arduino_dimmer_LED.sb2
Analog outputs can be used to control motors or position servos for example. You can try it.
Let's begin with connecting a push-button to Arduino pin 2. Follow the above diagrams and make the proper
connections.
From now on, we can go faster. You have already "catch" the idea!
For digital inputs, we will use the same setup block that we used with the LED, but changing its parameter to
"input":
And to "read" the value on this pin, we will use the block:
This block will return "1" if on the pin D2 we have a logical level "1" and "0" if it is a "0". Drag both blocks to Script
area and click first on the Enable block and after on the Read Digital block. Press the push-button and verify if the
status changed (a "white balloon" will appear over the block with its value).
So, let's create a new variable "button", that will be set up to "1" or "0" depending on the push-button condition and
2 new costumes for the new Sprite (we will call it Push-Button). Try it yourself and only after confirming with the
code at bottom of this step.
Again, we will create 2 groups of Blocks, the "setup" and the "main loop". Only note that here the variable "button"
will be "loaded" with the Push-Button status:
A great feature with Scratch that helps a lot when you are testing a code, is "to check" a variable (with a "v" mark)
on the Data menu. Doing that, the variable value will be shown at Stage, as shown on the above screenshot.
Let's Create a code associated with MJRoBot Sprite that will vary pwmLED from minimun (0) to maximum (255),
but only during the time that Push-Button is pressed. Also, if the Push-Button is pressed, the RED LED
(associated with led variable) must be ON. Try it yirsel before look the final code.
After you have tried, you can download my version of the above problem.
Arduino_Push_Button_LED.sb2
For learning how to use the Arduino analog inputs, we will connect an LDR, that is a Light Dependent Resistor on
Analog Pin A0.
LDR, also known as " Photoresistor", is a device that has its electrical resistance varying with light. As you can
see above diagram, higher the light, lower the resistance. So, because we will assemble the LDR as a "voltage
divider", we will get at Arduino pin A0 an analog signal inversely proportional to light variation:
High light ==> Lower internal resistance ==> higher voltage input at A0
Low light ==> higher internal resistance ==> lower voltage input at A0
This way, the pin A0 of Arduino UNO will receive a signal varying from 0 to 5V. The Analog Pins of UNO are
internally connected to a 10bits ADC (Analog Digital Converter), that it is a device that as the name explains, will
convert the analog value to a digital value that can be read internally by the processor (10 bits ADC generates
values from 0 to 1023).
So, on a limit:
LOW LIGHT ==> LDR with HIGH RESISTANCE ==> 0V at pin A0 ==> ADC: 0
HIGH LIGHT ==> LDR with LOW RESISTANCE ==> 5V at Pin A0 ==> ADC: 1023
of course in a practice, the values will be between those extremes. Let's see it working:
And to "read" the value on this pin, we will use the block:
So, let's create a new Sprite (LDR) and a new variable "light", that will a value depending on ambient luminosity.
The problem here is that 800, 900, 50, etc that is the values returning from ADC means nothing for us. What we
need is something like:
So, if we have a luminosity of 30%, for sure is the end of the day and we know what really means.
And any value intermediary (from 0 to 1000) will proportional to a value from 0% to 100%:
We can generate here a generic block that will MAP an analog input, independent of the values that we have that
will transform from minimum (Low) and maximum (High) inputs to a minimum and maximum outputs.
and
Seems a little complicated, but in fact is simple and useful. The important here is that this "Map Block" that you
create will work always. Also, note that we have used the operator "Round" that will as its name says, round the
final value. At the end you will only need to use:
On our case:
Electronic Playground With Arduino and Scratch 2: Page 15
map (Read Analog Pin (A) (0)) (30) (1000) (0) (100)
and we will set our light variable with the return of this new map block. For more details about MAP, see see here.
Let's go to our MJRoBot Sprite and use this new variable light, creating a simple code where if the light is less than
30%, we must turn on the Red LED (associated with variable led), if not leave the LED OFF. Spite of simple, this
is exactly what happens with street lights for example, that automatically turn ON at end of day.
My code: Arduino_LDR.sb2
Challenge:
Modify your code to automatically turn on an external light in your house (here the red LED) when is dark, but you
only want to do this if you are traveling, so you will turn on or off your project, using the push-button. Think about
how you must play with variables in a way that when you "press the push-button", we keep its status. If we press it
again, the status will be "toggled".
Let's explore another sensor that also generates an analog output, the LM35, a temperature sensor.
The LM35 series are precision integrated-circuit temperature sensors, whose output voltage is linearly proportional
to the Celsius (Centigrade) temperature and so, does not need external calibration. Its output is 10mV/oC. So, for
Electronic Playground With Arduino and Scratch 2: Page 16
a temperature of 19 oC for example, the LM35 will generate 190mV.
As we did before, we will create a new Sprite (LM35) and define a new variable, "tempC" that will receive the
analog pin A1 value. The setup is similar to what we have done with LDR, only we will change (A) (0) for (A) (1) on
Enable Analog Pin block.
And to "read" the value on this pin, we will use the block:
Ops, but when you click on this block, we realize that the temperature is not really correct (it shows "39", but I
know that the temperature here in my lab is in fact 19oC).
What's wrong?
Remember that each Analog Input will vary from 0 to 5V (or 5,000mV). So, let's calculate for 19oC what should be
the output of internal ADC:
So, this is exactly what we are getting internally from A1. But what should we do have the variable "Temp"
showing the correct Celsius temperature?
Taking the reading, find what percentage of the range (1024) it is, multiplying that by the range itself (5000 mV),
and dividing by ten (10 mV per degree Celcius, according to the datasheet):
When you click on it, the correct "19oC" will appear associated with variable "tempC".
Note that we at the final code will use round () to "round" the result of the calculation, taking out the value after the
Electronic Playground With Arduino and Scratch 2: Page 17
decimal point.
Same as we did with LDR and now that we have the variable tempC constantly updated with the sensor value,
let's create a code associated with our MJRoBot Sprite, having the following idea:
Note that we are keeping the previous code, that will turn on the "red LED" if the light is lower than 30% and now
we are adding an "alarm" using the "blue LED", related with our variable pwmLED. Both sensors will work
independently.
In reality, the Arduino UNO has only one internal ADC that is multiplexing amont its 6 analog pins. So, its good
not to have measurements imidiatelly one after the other. Its advise to have at least 300ms between
measurements.
Returning to our project, you can imagine it to be used to automatically turn on a fan or conditioner air equipment
in your house (here the blue LED) when is hot. Put your finger over the sensor. You should see the temperature
going up, firing up the blue LED.
Arduino_Temp.sb2
Chalenge:
Create a code that will draw a "Bulb Thermometer", where the mercury column will go up and down accordantly
with temperature (see the above picture as an example).
PIR sensors allow you to sense motion, usually used in home alarms to detect whether an intruder has moved in
or out of the sensors range. They are small, inexpensive, low-power, easy to use and don't wear out. For that
reason, they are commonly found in appliances and gadgets used in homes or businesses. They are often referred
to as PIR, "Passive Infrared", "Pyroelectric", or "IR motion" sensors.
They are "Digital Sensors", being very easy to use them in your projects:
If you have a "movement" in front of the sensor, its will generate a 5V in its output and the Arduino
will understand it as logical level "1".
With "no movement" a 0V will be at Arduino's digital pin, what means a logical level "0".
You can "think" that the sensor is a "push-button", what means that what we have learned before will apply to it.
So, let's begin with connecting the PIR sensor to Arduino pin 3. Follow the above diagrams and make the proper
connections.
Same as we did with the Push-Button, let's create a Sprite (PIR), this time with 2 costumes showing if we get or
not a "movement" and a new variable named "motion". Use an Enable Digital Block to setup the pin:
And to "read" the value on this pin, we will use the block:
This block will return "1" if on the pin D3 we have a logical level "1" and "0" if it is a "0". Try it.
So, we need now set up the variable "motion", with 1 or 0, depending on the PIR condition:
As we did before, the variable, "motion" will take the D3 status. We will include it on the "Forever Loop" that is part
of the "main" function. At this loop, we should test if there is movement (motion = 1) and change the Sprite's
costume properly.
Now, let's think about something useful to do with this sensor. As mentioned before, the PIR is commonly used on
home alarms. If a person enters in your home, the sensor will detect it and will fire an alarm for example. In our
case, this alarm is represented by the red LED. The code is similar to the one developed for the last sensors.
Arduino_Motion_Detector.sb2
Challenge:
Modify your code to automatically turn on an external light in your house (here the red LED) when is dark, but you
only want to do this if you are traveling, so you will turn on or off your project, using the push-button. Think about
how you must play with variables in a way that when you "press the push-button", we keep its status. If we press it
again, the status will be "toggled". Also, now consider to include in the code the movement sensor.
Up to now, the Sprites that we have developed used a "straight forward" approach:
From now on we will explore new blocks developed on s2aio, the first ones will be related to "Tone Generation":
Those blocks will generate a square wave of the specified frequency (and 50% duty cycle) on a pin. A duration can
be specified in milliseconds, otherwise, the wave continues until we use a noTone block. The pin will be connected
to a piezo buzzer to play tones. Follow the above diagram and connect the pin "+" of the buzzer to digital Pin 6.
You must configure the pin for tone operation by using the Digital Pin Configuration Block before using this block.
For sending a specific tone to the Piezzo use the Play Tone Block, for example, for 1KHz and 500ms tone:
Entering a duration of zero will leave the tone activated. Use the no tone command block to deactivate.
Great! Remember our last step where we had a motion detector? let's now associate a sound alarm (Buzzer) when
an intruder is detected! On my example, I used 2 different frequencies to simulate an alarm. Try other ideas!
Arduino_Buzzer .sb2
A very interesting device that can be used for distance measurements is the "Sonar". Here we will be using the
HC-SR04 Ultrasonic Ranging Sensor.
Basically, this device emulates what bats do for distance measurements. They emit an ultrasound pulse and count
the time for an echo to be received back. Having the time for the Echo to reach back the sensor and knowing the
sound speed (340m/s), we can by dividing it by 2, knowing the distance between sensor and obstacle (see above
diagram).
This sensor provides 2cm to 400cm of non-contact measurement functionality with a ranging accuracy that can
reach up to 3mm. Each HC-SR04 module includes an ultrasonic transmitter, a receiver and a control circuit.
The HC-SR04 has 4 pins:
VCC (Power),
Trig (Trigger),
Echo (Receive), and
GND (Ground).
The pin 12 should be enabled using the Digital Pin Configuration block, selecting Sonar mode.
If you do the above, you will get the sensor working, BUT you will realize that sometimes, errors will happen (big or
very low measurements). This is because other sound or echoes reflected on different obstacle can generate
"false" responses to the sensor. One way to minimize this, it to create a temporary variable ("temp"), that will
receive the reading from Digital Pin. We will only pass this value to our real variable "distance" IF the
measurement is in between defined limits (see the above print screen). For example, I have setup an area to
measure things that will go from a minimum of 3 cm up to a maximum of 40 cm.
Great! Remember our last step where we developed a sound alarm with our motion detector? Let's now associate
the sound alarm (Buzzer) and a visual alarm (LED) when an intruder is detected but ONLY on distances less than
30cm (SONAR)! Try other ideas, like also incorporating the motion sensor (PIR) more LEDs, light, etc.
Arduino_Sonar.sb2
Our last device to be included on the MJRoBot Electronic Playground will be a servo motor, using another special
s2aio command block to set its position between 0 and 180 degrees.
But before anything, Let's build a "tower" where we will mount together with the Sonar and the 180 degrees Servo
Motor. Doing that, we can point our sonar in different directions, using the servo. Follow the above photos as a
suggestion how to build the tower.
Having the tower fixed on a table (I used Scott tape), connect the servo cable on protoboard as shown at the
diagram. There are only 3 wires, +VCC, GND and Data (usually orange) that must be connected to Arduino pin
D10.
The pin 10 should be enabled using the Digital Pin Configuration block, selecting Servo mode.
The command to position the Servo on specific angles is gotten with Move Servo block. Below an example moving
it to 20 degrees:
Make some tests, changing angles from 0 to 180 (sometimes you must adjust the final values, the servo motor can
have problems at extremes (near 0 and near 180)
If you do the above, you will get the servo working, BUT it is important to prevent that variable angle be defined by
other Sprites with values out of servo range (in my case 20 - 180). So, we will make a "limitation" or
"CONSTRAIN" the data angle, in a way that we will only move the servo if variable angle will be between 20 and
180. If the angle is lower than 20, we will keep it 20, same procedure for values over 180. See the above print
screen to understand how I create this "constraint idea".
A good procedure will be create a dedicated and generic block for the "CONSTRAIN function", same we did for
MAP. Try it!
Let's create a "SWAP" function, where the servo will move in all directions. Let's include the pushbutton, so the
Servo will make the swap only when it is pressed.
Arduino_Servo.sb2
Now our MJRoBot Electronic Playground is complete. We have a Sprite for each one of our components. Each
component has a variable associated with it. So, now we can define a project and work on its code only changing
the Script associated with MJRoBOt or any other.
The idea is not change the component sprites if the HW not changed.
So, let's create our first real project using the Playground.
Base_Playgroun d.sb2
You will see that the Script area for our Sprite MJRoBot is empty.
To create a new project, go to Scratch 2 Offline Editor File Menu and using "Save as" option name it:
"Arduino_Radar_Basic.sb2". Do not change the Base_Playground.sb2 file.
Using what we have learned so far, we will create a code for a base radar where:
1. The tower with Servo/Sonar will sweep an area looking for obstacles on a 40 cm range.
2. If an obstacle is found on distance less than 10 cm, an alarm should be fired.
3. The alarm should use sound and light.
That's it. The video below shows how the final project should work:
//www.youtube.com/embed/4NBhU1sFero
Arduino_Radar_Basic.sb2
Let's use our last project, the "Base Radar" and also include on it an animation that will show a "Radar Screen" on
our Stage area.
The Radar Screen will only a "background" and will be static. But the Radar Scanner will be a Line that will sweep
the Radar screen from left to right (from 0 to 180 degrees), following the Servo Sweep.
In order to, synchronize the animation and the real servo swap, you must add to MJRoBot's last script, two "event
calls"
The first any time that the servo goes to its start position:
broadcast [startScan]
broadcast [draw]
and one more, when a target is found and the alarm is fired off:
broadcast [target]
//www.youtube.com/embed/ZyDJsyp8UAs
Arduino_Radar_V2.sb2
Be creative! Mix the sensors, including new ones! The sky is (not) the limit. After you learn about how to control
"things" using an Arduino and Scratch 2, try doing the same using the Arduino IDE.
As always, I hope this project can help others find Saludos from the south of the world!
their way in the exciting world of electronics, robotics,
and IoT! See you at my next instructable!
Scratch_2 Marcelo