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.

Figure 4: The Make a block wizard allows you to extend Snap!.

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.

Figure 5: You use the editor to build functions and routines.
Figure 6: A new wizard allows you to add more elements to the block definition.
Figure 7: The Create input name dialog lets you set a parameter's name and type.

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.

Figure 8: The factorial block code.

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

Figure 9: The result of your block will show up as a speech bubble in the workspace.

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.

Figure 10: Snap! interacts with web servers running on the hardware to send and receive information.

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.

Figure 11: This block will set the state of a pin on the Raspberry Pi.
Figure 12: What the block in Figure 11 looks like "from the inside."

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.

Figure 13: Right-clicking on the Default Value text box lets you …
Figure 14: … access the Input slot Options, where you can specify the options to use for your block's parameters.

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.

Buy this article as PDF

Express-Checkout as PDF

Pages: 9

Price $2.95
(incl. VAT)

Buy Raspberry Pi Geek

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content