A web-based alternative to Scratch
Building Blocks
You can easily create new blocks in Snap! by right-clicking on the central workspace and choosing Make a block from the pop-up dialog. Snap will then bring up a wizard like you see in Figure 4.
You can decide which category your block will go under and whether it will be a Command (executes a series of instructions without returning a value), a Reporter (executes a sequence of commands and returns a value), or a Predicate (similar to a Reporter, but returns a True
or False
to be used in conditions).
Because you will be seeing examples of how to build a Command and a Predicate later when I get into reading and writing to the Pi's GPIOs, I'll first demonstrate how to create a Reporter. In this exercise, you will create a block that, given a positive integer number, returns its factorial (n! = 1 x 2 x 3 x 4 x … x n).
Within the wizard window, click on the Operators button, because that is where you are going to store your block. In the text box, type !
. This will appear as text on the block itself. Next, click Reporter and then OK.
You will see something like what is shown in Figure 5. The two plus signs on either side of your !
are placeholders for more text or parameters. In this case, you're going to click on the first +
. A new dialog will pop up (Figure 6), and you must type number
in the text box and select Input name (i.e., parameter). Then, click the little right-pointing arrow to the right. This will unfold a much larger dialog that allows you to pick the parameter's type (Figure 7). Choose Number and click OK.
Now you have the definition, but the block doesn't actually do anything yet. You're going to need a new variable for that; so, in your workspace, click on Variables and then on Make a variable. Call your new variable result
.
Then, within the Block Editor, build a script like the one in Figure 8.
When you're done, click OK and your block will appear under Operators.
Now you can drag the block out onto the workspace. Click within the number slot and type, for example, 5
. Next, click on the block and the result (120) should show up in a bubble in the workspace and in a lozenge in the upper left-hand corner of the stage at the upper right (Figure 9).
This factorial block is just a dumb example that does not work very well. If you were to input a
, a negative number, or a number with decimals, it would fail miserably. You can experiment with improving it by taking all those possibilities into account.
When you're done, if you want to save your block, click on the File button (the paper icon with the folded corner) in the toolbar and select Export blocks. Select the blocks you want to export from the list and click OK. A new window or tab will open in your browser with something that looks like Listing 1.
Listing 1
Factorial.xml
01 <blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"> 02 <block-definition s="%'number' !" type="reporter" category="operators"> 03 <header/> 04 <code/> 05 <inputs> 06 <input type="%n"/> 07 </inputs> 08 <script> 09 <block s="doSetVar"> 10 <l>result</l> 11 <l>1</l> 12 </block> 13 <block s="doUntil"> 14 <block s="reportEquals"> 15 <block var="number"/> 16 <l>0</l> 17 </block> 18 <script> 19 <block s="doSetVar"> 20 <l>result</l> 21 <block s="reportProduct"> 22 <block var="result"/> 23 <block var="number"/> 24 </block> 25 </block> 26 <block s="doSetVar"> 27 <l>number</l> 28 <block s="reportDifference"> 29 <block var="number"/> 30 <l>1</l> 31 </block> 32 </block> 33 </script> 34 </block> 35 <block s="doReport"> 36 <block var="result"/> 37 </block> 38 </script> 39 </block-definition> 40 </blocks>
You can now save this file as Factorial.xml and later import it back into Snap! using the Import option in the File menu.
Notice how clever this is: All the individual blocks that make up your custom block are contained within this XML file. For example, the section
<block s="doSetVar"> <l>number</l> <block s="reportDifference"> <block var="number"/> <l>1</l> </block> </block>
contains the part that decrements the number
variable by one.
Hello (Outside) World
If you want Snap! to interact with the hardware, things get a little stickier. JavaScript, by design and for security reasons, is not allowed to interact with a machine's hardware. Browsers execute JavaScript scripts within a virtual and airtight sandbox to prevent evildoers from messing with your computer from the web.
How do you overcome this limitation? As usual, with Snap! – very cleverly as it turns out. JavaScript can't interact with hardware directly, granted, but it can interact with other web servers, sending data to them using the GET method, and it can also receive data back in the shape of web pages. Finally, a web server can interact with the underlying hardware (and other non-web software) it is running on.
So, you need to set up a web server on your Rasp Pi. Snap! sends a GET request with parameters to the server. The server interacts with the hardware, reading or writing to the GPIOs and then, if required, builds a dynamic web page to send back to Snap!. Next, Snap! extracts the data from the page and uses it in its program. You can see a summary of how this works in Figure 10.
I'll clarify how this would go down on the Rasp Pi with a real-life example. First, open the block editor and create a Command block like the one shown in Figure 11. This block will send a HIGH or LOW signal to a certain GPIO pin. You can use this to switch an LED on or off, for example. You can see what the block's internal design would look like in Figure 12 and the corresponding XML in Listing 2.
Listing 2
pinwrite.xml
01 <blocks app="Snap! 4.0, http://snap.berkeley.edu" version="1"> 02 <block-definition s="set BCM2835 pin %'pin' to %'state'" type="command" category="looks"> 03 <header/> 04 <code/> 05 <inputs><input type="%n" readonly="true"><options>0 06 1 07 4 08 7 09 8 10 9 11 10 12 11 13 14 14 15 15 17 16 18 17 21 18 22 19 23 20 24 21 25</options></input><input type="%txt" readonly="true">LOW<options>LOW 22 HIGH</options></input></inputs> 23 24 <script> 25 <block s="doRun"> 26 <block s="reportURL"> 27 <block s="reportJoinWords"> 28 <list> 29 <l>192.168.1.114:8280/pinwrite?pin=</l> 30 <block var="pin"/> 31 <l>&state=</l> 32 <block var="state"/> 33 </list> 34 </block> 35 </block> 36 <list></list> 37 </block> 38 </script> 39 </block-definition> 40 </blocks>
You may notice something in the XML that is not visible in the Snap! block definition of the command: A list of possible values for your two parameters. Here, pin
can take only the numbers that designate valid GPIO pins on the RPi you can write to, and state
can take LOW
and HIGH
as values (the default value being LOW
).
To assign a list of options to a parameter, right-click on your block and choose edit from the pop-up dialog to open the block editor. Click the parameter you want to change (e.g., pin
or state
) and then the right-pointing arrow in the Edit input name dialog.
In this extended dialog, make sure you have the Single input radio button selected at the bottom. Right-click on the Default Value text box to open a new pop-up menu (Figure 13). Clicking options lets you input your options, one per line (Figure 14). Finish by clicking OK. If you want to make sure your user only inputs something from your list and doesn't type anything else, right-click the Default Value text box again and mark the read-only checkbox.
You might also notice that the block calls http://192.168.1.114:8280/…. That's the server running on the Rasp Pi, and 192.168.1.114 is the IP of my Raspberry Pi on my local network. You will have to change that to whatever your Pi's IP is on your network.
« Previous 1 2 3 4 Next »
Buy this article as PDF
Pages: 9
(incl. VAT)