Block I Illinois Library Illinois Open Publishing Network

Blue Unit: Computational Tinkering

3B: Build Functions for Remixable Code

Background Knowledge Probe

Reusing/remixing code is a central tenet of the free and open source software movement. And indeed, it’s a central tenet of the Internet, as we’ll discover in the Rainbow Unit. But as we’ve discovered throughout the book and especially highlighted in The Unknown Tech Innovators, there’s also an active work to give the credit for innovations to certain people, and particularly to white males.

Take a few minutes now to reflect back on the innovative designers and builders of the code we’re now using for our own Community of Practice works, and especially those hidden and forgotten that we’ve worked to bring forward as part of our explorations.

    • How has their work helped shape your own use and reuse/remixing works?
    • In what ways might your remixes be used by others in their works?

Technical Review

Let’s take a minute to reflect back on the final exercises in sessions 1 and 2. Note that in the “Five Digit Counters” exercise, we used a range of and to expand our opportunities for collecting and sharing data using several .The five-digit counter exercise is completed in block code using the MakeCode website.Compare this to the “Middle C Scale Toolbox Trumpet” exercise. Here, we committed our attention to deductive reasoning and to guide us in the creation of an appropriate, functional sequence of , thereby playing the notes in order from Middle C to Middle B.
Two programming loops are represented in block code. An 'on start' sets the volume to 255. In a forever loop, the Circuit Playground Express is programmed to play the middle C scale.

Exercise: Variables & Functions Remix of the Toolbox Trumpet

Let’s begin by considering how we could remix the Toolbox Trumpet using variables and functions to expand the capabilities of this tool.

Steps: Creating a binary to decimal calculator

To begin, we will create a new variable and use conditionals to collect the values, 000 to 111, provided using the three “valves.” We will use this to calculate the decimal notation equivalent, 0, 1, 2, 3, 4, 5, 6, or 7.[1]

  1. In the VARIABLES category, create a new variable called CapTouchCounter. This will be used to determine which capacitive touch sensor “valve” or “valves” are pressed in that sequence.
  2. Drag a “set CapTouchCounter to 0” block from the VARIABLES category and place it in the default FOREVER function.
  3. Add three “If…Then” blocks from the LOGIC category to the FOREVER function, and configure them using a “button A is pressed” block from the INPUT category to have conditionals for pin A1, pin A2, and pin A3.
  4. In each of the “If…Then” conditionals, add a “change CapTouchCounter by” block. Set the pin A1 conditional so that CapTouchCounter is changed by 1. Set the pin A2 conditional so that CapTouchCounter is changed by 2. Set the pin A3 conditional so that CapTouchCounter is changed by 4.
  5. Under advanced, go down to the CONSOLE category. From there, drag a “console log” block and add it as the last line of code in the new FOREVER function.
  6. Finally, from the VARIABLES category, drag a “CapTouchCounter” block and drop it into the right oval window of the “console log” block.

Here’s a video screenshot of these steps to compare with your own process. Feel encouraged to change 1X to 2X to play it back at high speed. Note that the console provides a means to enter a new level of testing within the simulator. Remember that we cannot test the pressing of multiple capacitive touch sensors simultaneously. At this point, we can only assume the “change” statement will add in the value, rather than replacing the previous value.

Steps: Playing the Middle C Scale

As we move forward, much of the time we use our Circuit Playground Express, we may want to use these to select a digital counterstory to play through speakers rather than playing the notes of a C scale. Sometimes we may want to do both. Sometimes we’ll want to use the calculations for yet other purposes.

For this reason, we will now create a new function called playTrumpetNote. We’ll pass the CapTouchCounter value to the function and set it up to determine the Hertz the note should be played at.

  1. From within the ADVANCED category, open the FUNCTIONS category. Within FUNCTIONS, click on “Make a Function.”
    • Replace “doSomething” with the name playTrumpetNote.
    • Add a parameter “Number” and replace “num” with “decimalNotation.”
      In the Edit Function window, a function named 'playTrumpetNote' has the number parameter 'decimalNotation.'
  1. From the FUNCTIONS category, drag the “call playTrumpetNote 1” and drop it at the bottom of the current FOREVER function, beneath and NOT WITHIN the end of the “If pin A4 is pressed Then” block.
    At the bottom of the forever loop, a 'call playTrumpetNote' function passes the CapTouchCounter variable. To the right of the forever loop, the function playTrumpetNote which passes the decimalNotation variable, is highlighted.
  1. Drag a “CapTouchCounter” block from the VARIABLES category and drop it into the “call playTrumpetNote 1” function, replacing the number 1.
    • A number from 0 to 7 will now be sent to the function playTrumpetNote every time we call it.
  1. We’ll now use eight “If…Then…ElseIf” logic tests to work through the possible different decimal notation values we may receive given the 0 to 7 decimal scale we might receive via the function call.Within the playTrumpetNote function, eight 'If... Else if' logic statements are added.
  1. In the VARIABLES category, create a new variable called Hz.
  2. Drag the “set Hz to 0” block into the “If decimalNotation = 0” logic statement.
    • When the variable decimalNotation is equal to 0, no capacitive touch sensors are currently pressed, so no note should be played.
  1. Copy and paste this “set Hz to 0” 7 times, putting one in each of the remaining “If decimalNotation =” logic statements. Set the Hz to the following numbers:
decimalNotation Note Hz
0 Silent 0
1 Middle-C 262
2 Middle-D 294
3 Middle-E 330
4 Middle-F 349
5 Middle-G 392
6 Middle-A 440
7 Middle-B 494
  1. From the LOGIC category, drag over one additional “If…Then” logic statement and add beneath the last “else If decimalNotation = 7 Then” conditional.
  2. To this new “If…Then” logic statement, replace “True” with a “<0 = 0>” comparison statement from the LOGIC category, within the Comparison section.
    • Replace the left 0 with a “decimalNotation” variable block.
    • Change the “=” comparison to a “>” comparison.
  • This will assure that a tone will only be played if one or more of the “valves” is pressed.
  1. Finally, from the MUSIC category, drag a “play tone at Middle C for 1/2 beat” and place it within the new “If decimalNotation > 0 Then” conditional statement.
  • Drag a “Hz” block and drop it into the “play tone at Middle C for 1/2 beat” block, replacing the “Middle C” window.
  1. Take a few minutes to test this out in the simulator. Then save this as ToolboxTrumpetMiddleC-variablesFunction, and flash it to your physical Circuit Playground Express for further testing.

The completed Middle-C Scale exercise using variables and functions in the block code workspace. A forever loop includes the following blocks: 'Set CapTouchCounter to 0. If pin A1 is pressed, then change CapTouchCounter by 1. If pin A2 is pressed, then change CapTouchCounter by 2. If pin A4 is pressed, then change CapTouchCounter by 4. Call playTrumpetNote CapTouchCounter.' Below, an 'on start' sets volume to 255. At right, the function playTrumpetNote with variable decimalNotation states: 'If decimalNotation = 0, then set Hz to 0. Else if decimalNotation = 1, then set Hz to 262. Else if decimalNotation = 2, then set Hz to 294. Else if decimalNotation = 3, then set Hz to 330. Else if decimalNotation = 4, then set Hz to 349. Else if decimalNotation = 5, then set Hz to 392. Else if decimalNotation = 6, then set Hz to 440. Else if decimalNotation = 7, then set Hz to 494. If decimalNotation is greater than 0, then play tone at Hz for 1/2 beat.'

Key Takeaways

Functions serve to run certain control flow statements and other code when called upon by other parts of the program. Indeed, MakeCode itself is written using many thousands of lines of code, most of which we do not see or even know about. But within that code, they make a call to the FOREVER function we create. This is the MakeCode implementation of the Clocked Sequence Programming I did as a graduate student back in 1990 to collect data from a controller I designed to do my own research. Then it was in the C programming language, but the lines of code themselves have a lot of similarities.

By moving the playing of a note into its own function, we can now use the more general capTouchCounter value for a wider range of activities beyond just playing a note in a C scale, and potentially even instead of that.

Indeed, take a moment to drag an “If…Then” logic block from the LOGIC category and drop it around the “call playTrumpetNote CapTouchCounter” block. Then, at the very bottom of the INPUT category, drag out a “switch right” block and replace the “True” statement within this “If…Then” logic block. Save and flash this to your Circuit Playground Express. Now, depending on the position of the slide switch located at D7 on the Circuit Playground Express, the notes of your scale will or will not be played when pressing the “valves.” However, the CapTouchCounter values will still be calculated, as seen if you use a CONSOLE category “console log” block to record the “CapTouchCounter” value.

At the bottom of the forever loop, a console log calling the CapTouchCounter is added.

Exercise: 4-Octave Toolbox Trumpet

In “Essential Coding Concepts,” we set up the momentary switch push buttons so that the blue LED was on unless button A was pressed, and the white LED was off unless button B was pressed. Essentially, this was equivalent to:

  • No buttons = 1 LED
  • Left button = 0 LEDs
  • Right button = 2 LEDs

This design could be seen as equivalent to the Middle C scale with no buttons pressed, Low C scale with button A pressed, and High C scale with button B pressed. Let’s do a remix of our code to see how an electronic device can do the same thing, sometimes with added functionality, by remixing the lines of code. To do this, we’ll add these calculations into the FOREVER function, and then pass them on to the playTrumpetNote function.

Steps and images are provided. Or, you can download the completed file:

circuitplayground-ToolboxTrumpet4Octave-variablesFunc.uf2

Open and review it in MakeCode, and flash it to your Circuit Playground Express for further prototyping.

The completed 4-Octave Toolbox Trumpet exercise in the block code workspace. A forever loop includes the following blocks: 'Set CapTouchCounter to 0. Set buttonCount to 1. If pin A1 is pressed, then change CapTouchCounter by 1. If pin A2 is pressed, then change CapTouchCounter by 2. If pin A4 is pressed, then change CapTouchCounter by 4. If button A is pressed and button B is pressed, then set buttonCount to 3. Else if button B is pressed then set buttonCount to 2. Else if button A is pressed then set buttonCount to 0. If switch right then call playTrumpetNote with variables CapTouchCounter buttonCount. Console log CapTouchCounter.' At right, an 'on start' sets volume to 255. At right, the function playTrumpetNote with variables decimalNotation and buttonCount states: 'If decimalNotation = 0, then set Hz to 0. Else if decimalNotation = 1, then set Hz to 262. Else if decimalNotation = 2, then set Hz to 294. Else if decimalNotation = 3, then set Hz to 330. Else if decimalNotation = 4, then set Hz to 349. Else if decimalNotation = 5, then set Hz to 392. Else if decimalNotation = 6, then set Hz to 440. Else if decimalNotation = 7, then set Hz to 494. If buttonCount = 0 then set Hz to Hz divided by 2, else set Hz to Hz multiplied by buttonCount. If decimalNotation is greater than 0, then play tone at Hz for 1/2 beat.'

The key additions:

  • Add a new variable called buttonCount to conduct three “If…Then” conditionals, setting buttonCount to 0 if only Button A is pressed, to 2 if Button B is pressed, and to 3 if both Button A and Button B are pressed. Otherwise, buttonCount remains at its default of 1.
  • Pass buttonCount as a second number to the function playTrumpetNote.
  • Divide the variable Hz by 2, taking it down one octave, if buttonCount is 0. Else, the variable Hz is multiplied by buttonCount. If neither button was pressed, it equals 1 and the Hz stays in the middle octave. If button B is pressed, the Hz is multiplied by 2 and it goes up one octave. If both buttons are pressed, it is multiplied by 3, and the Hz goes up two octaves.

Steps

  1. Create a new variable called buttonCount. At the top of the FOREVER function, add a “set buttonCount to 1” block so that in each iteration, this value is reset to the value if neither button is pressed.
  2. Add a new set of “If…Then” logic statements, such that:
    • If button A is pressed and button B is pressed, then set buttonCount to 3.
    • Else if button B is pressed, then set buttonCount to 2.
    • Else if button A is pressed, then set buttonCount to 0.
  3. Right click on the “call playTrumpetNote” and select “Edit Function.” Add a new number parameter and call it “buttonCount.”
  4. In the “call playTrumpetNote” function, add a “buttonCount” block as the second number in the function call.
  5. Between the “decimalNotation” “If…Then…ElseIf” logic statements and the “If decimalNotation > 0 Then” conditional statement, add in a new “If…Then…Else” logic block from the LOGIC category. Configure this sequence of lines of code such that:
    • If buttonCount = 0, then set Hz to Hz ÷ 2.
    • Else, set Hz to Hz × buttonCount.

Wrap Up

We should now have two variables, CapTouchCounter and buttonCount, that we can pass to functions. As a part of the “Comprehension Check” for this session, let’s next look at how these variables can be remixed in different functions.

Comprehension Check

Do Something New!

We’ve used the LED Pixels as indicator lights and even 5 digit counters in a few exercises now. As a “Comprehension Check,” create a new LED Pixel Counter function to do the same with our Toolbox Trumpet. Indeed, this can prove helpful if we’ve forgotten we have the sliding switch to the left, keeping the Toolbox Trumpet notes from being played by the Circuit Playground Express speaker. Record a video image of this being run from your physical Circuit Playground Express, as well as a copy of a screenshot of this new function as a way of demonstrating you’ve learned the core steps to create a new function.

Design Criteria

  1. Open up the “ToolboxTrumpet4Octave” project in MakeCode. Rename this as “ToolboxTrumpet4Octave-pixelCounter” and click on save.
  2. Create a new function called “pixelCount” and add in the number called “digitalNotation” and the number called “buttonCount.”
  3. Create blocks of code such that pixel 9 is one of four colors, depending on the value of the variable “buttonCount.”
  4. Create blocks of code such that pixels 0 to 6 are turned on to match “digitalNotation − 1” and off if no values are pressed.

Here’s a short video demonstrating a simulator test of the prototype I created.


  1. MakeCode © 2020 Microsoft and Adafruit. Screenshots used with permission.

License

Icon for the Creative Commons Attribution-ShareAlike 4.0 International License

A Person-Centered Guide to Demystifying Technology, 2nd Edition Copyright © 2023 by Martin Wolske Copyright © 2023. Copyright “Ideating and Iterating Code: Scratch Example” © 2020 Betty Bayer and Stephanie Shallcross. Copyright “Introducing the Unix Command Line” © 2020 Martin Wolske, Dinesh Rathi, Henry Grob, and Vandana Singh. Copyright “Security and Privacy” © 2020 Sara Rasmussen. Copyright “Storytelling in the Information Sciences” © 2023 Yingying Han and Martin Wolske. This book is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License, except where otherwise noted.

Share This Book