Block I Illinois Library Illinois Open Publishing Network

Rainbow Unit: Networks Big and Small

1B: Connecting Our Electronic ‘Thing’ to a Wider World

Technical Overview

As we saw at the end of the Orange and Blue Units, there are many ways to provide data communications between devices. In the Orange Unit, we learned more about the ports available on our computers, such as the and ports, that provide ways for us to connect external devices such as keyboards, mice, and monitors. And in the Blue Unit, we learned about serial data communications interfaces such as the interface we’ve been using to transmit and receive data between the Raspberry Pi and the screen or PuTTY console of our laptop, and between the Circuit Playground Express and our Raspberry Pi. While technically a keyboard and a computer or a microcontroller and a microcomputer are two separate devices, via the software we use, they work as one unified system. They are our computer. They are our counterstory trumpet.

But underlying the concept of the Internet of Things — which today is often popularly referred to as Smart Devices coming together to create Smart Homes, Smart Grids, Smart Cities, and more — is an interconnection of electronics. A mechanical keyboard connected to a personal computer is not an IoT device. But a programmable keyboard that uses machine learning to predict changing contexts based on data from a range of local IoT devices and functionally evolve accordingly would be an IoT keyboard. It is to create an Internet of Things, whether or not this is connected to the physical Internet. There are actually many choices that can be made regarding this interconnectivity, only some of which make use of the Internet Protocol, something we’ll learn more about in session two of the Rainbow Unit.

Data Transport

As the evolution of computer networking continued into the 1970s, a number of different government- and corporate-sponsored programs led to the development of protocols, standards, and frameworks for data, information, and communication distribution between computers. This included CYCLADES in France, NPL network in the UK, and ARPANET in the United States. Through extended work by international bodies such as the International Organization for Standardization (ISO) and the Telecommunications Standardization Sector of the International Telecommunication Union (ITU-T), an Open Systems Interconnection (OSI) reference model was created and formally published in 1984 as both ISO 7498 and X.200. A key component of the OSI is a seven-layer model.

Seven layers of the OSI Model: 1. Physical: Copper & fiber cables, radio frequency & infrared wireless. 2. Data link: Media Access Control (MAC). 3. Network: Routing of data packets. 4. Transport: End-to-end connections. 5. Session: Interhost communication. 6. Presentation: Data translation & representation. 7. Application: What the 'end user' sees.

With regard to the Internet, these layers are practically combined into four groups, as follows:

Application & Presentation Layers Provide the physical client/server (e.g. web browser client/, server and , database server) or (e.g., Bittorrent, Bitcoin) applications with which end users work & the data translation and representation used in support of those applications
Session &
Transport Layers
Provide interhost communication and connections using protocols such as the and . While TCP is the most commonly used, leading to the standard TCP/IP suite reference, UDP is used when speed is prioritized over occasional dropped packets, for instance in live streaming and online gaming contexts.
Network Layer The core of the used to provide end-to-end routing of data packets across the backbone
Physical & Data Link Layers The unique identifiers associated with key hardware devices and the communications technology used to interconnect these devices

Limor Fried of Adafruit Industries partnered with DigiKey to create the web series “All the Internet of Things,” highlighting essential tools for building Internet of Things devices. Traditional Internet-based systems and structures combine the seven layers into four groups as listed in the table above. But Internet of Things applications often focus on the Physical and Data Link, Network, and Transport layers, as is highlighted in the video.

To prepare for our own work in the Rainbow Unit, watch the first 13 and a half minutes of Fried’s review of Ethernet and Wi-Fi transport.[1]

Data transfers between Internet of Things devices do not always (or even often) require human-computer interaction. The applications commonly used within Internet of Things devices do typically make use of common protocols such as HTTP and SQL that work within the Session and Presentation layers of the OSI model, but often can do so without the need for human-computer interfaces such as a web browser, or use the human-computer interface only occasionally for testing and configuration/programming purposes. In episode two of “All the Internet of Things,” Fried introduces us to commonly used application protocols including HTTP, which we’ll be using in the exercises below.

To get started, watch the first 4:10 of the video. For those wanting to do a deeper dive, you may consider watching through minute 11:04 to learn about the REST API (Application Programming Interface) that can be used with HTTP to create more extensive intercommunication between devices.[2]

Towards Our Own Internet of Things

In the following three exercises, we will work with the key components used to create IoT devices.

  1. First, we will return to the MakeCode Serial UART Communications Extension used with the Raspberry Pi Counterstory Digital Little Free Library exercises from session four of the Blue Unit. This time, we’ll add in temperature and light sensor data to the A1, A2, and A4 touchpad and A and B push button sensors. We’ll also include the current runtime of the Circuit Playground Express since it was last powered on or rebooted, providing five unique data points. We will transfer this data to the Raspberry Pi via the UART connection every second. A simple Python application run on the Raspberry Pi will then print these to a terminal window.
  2. Second, instead of displaying this data within a terminal window, we’ll display the data within a dynamic Hypertext Markup Language (HTML) document, viewable from a web browser client. Starting with Python version 3, Python code can be used to set up an HTTP server, watching for HTTP client requests for data. When a client request is received, the server dynamically creates an HTML page providing the real-time data, previously collected data, static text, or a combination of the above.
  3. Third, we will add the option to power LEDs on and off from a web browser. To accomplish this, we can use Python code, bringing together the HTTP server code from exercise two with code from the Coding Electronics chapter in the Orange Unit. Two options are available: The first uses the push buttons and LEDs as configured in the Orange Unit Coding Electronics chapter. The second uses a diffused RGB (Red, Green, Blue) LED to allow us to choose one of seven different colors for the LED display.

As we get started with these exercises, you may find it helpful to quickly review Blue Unit, Session 4, “Raspberry Pi Counterstory Little Free Library.” In particular, make sure you have your Circuit Playground Express connected to your Raspberry Pi using a TTL/USB Serial Cable. The TTL connects to the Circuit Playground Express using male to alligator clip wires. Disconnect the red wire from power (VOUT) on the Circuit Playground Express as we’ll be connecting the Circuit Playground Express to your personal computer with a microUSB to USB cable to edit the Circuit Playground Express code for these exercises.

Opportunity to Remix

These activities do not use databases or machine-learning code to create that true IoT device. Further, while both the Circuit Playground Express and Raspberry Pi devices are configured to transmit (TX) and receive (RX) data via the Universal Asynchronous Receive Transmit (UART) protocol, MakeCode currently does not support the RX pads on the Circuit Playground Express. For those wanting to do a deeper dive, follow Adafruit’s tutorial to use CircuitPython on the Circuit Playground Express, instead of MakeCode, to effectively use both the TX and RX pads and create a full serial bi-directional communications with the Raspberry Pi. Note: If you want to return to working in MakeCode after using CircuitPython, Adafruit provides instructions for uninstalling CircuitPython.

Exercise: Using Python to Monitor Sensor Information

First, connect your Circuit Playground Express to the Raspberry Pi using the USB to TTL cable. Connect the black to ground, white to TX, and green to RX. Leave the red VOUT disconnected; instead, connect the CPE to your laptop with a microUSB cable.

A diagram of the Circuit Playground Express to Raspberry Pi UART connection.

Let’s return to the MakeCode used within Blue Unit Session 4, circuitplayground-ToolboxTrumpet4Octave-WithUART.uf2. We can reuse that code, remixing it slightly to re-purpose the “serial write” so that it outputs sensor data. We’ll test out this modification using a new Python program instead of the previous

Here’s where we’re beginning:

In the MakeCode workspace, the completed 4 Octave Trumpet code combines with a new block: Within the On Start block, 'serial redirect to TX TX RX RX at rate 115200.' Within the forever loop, 'If CapTouchCounter > 0, then serial write number buttonCount; serial write number CapTouchCounter. Pause 1,000 ms.'

  1. Within the FOREVER loop, delete the “if CapTouchCounter > 0” LOGIC statement. This should also delete the two serial write number blocks within this if statement. Deleting this conditional “If…Then” logic statement is needed as we’ll want to transmit the serial write values whether or not the pads A1, A2, or A4 on the Circuit Playground Express have been touched.
  2. Add five new “serial write value “x” = 0″ blocks just above the “pause 1000 ms” block. These should be set up as follows. NOTE: value names are case sensitive as this will need to match the Python code run on the Raspberry Pi.
    1. ‘serial write value “Temp”‘ should be setup to transmit the INPUT “temperature.” It can be left as °C or changed to °F if you prefer Fahrenheit over Celsius.
    2. ‘serial write value “Light”‘ should be setup to transmit the INPUT “light level.”
    3. ‘serial write value “Runtime”‘ should be setup to transmit the CONTROL “millis (ms),” that is, the number of milliseconds elapsed since power on.
    4. ‘serial write value “Note”‘ should be setup to transmit the VARIABLE “CapTouchCounter.”
    5. ‘serial write value “Button”‘ should be setup to transmit the VARIABLE “buttonCount.”
  • NOTE: Previously we transmitted a number. These are sent in 1-byte packets (1 byte = 8 bits). These numbers, which were in the range of 0-4 and 0-7, were predictably sent as a single 1-byte packet. Moving forward, values such as Runtime will range, requiring 1 or more byte-sized packets. In MakeCode, the easiest alternative is to send each as a complete line of data that ends with a carriage return and line feed. In this way, they can easily be displayed line by line in a console window, just as if you were typing in the data using a keyboard and then hitting the “Enter” key at the end of each line of data. Your lines should now look something like this. Note the two new sensor icons within the simulator window:Block code in the MakeCode workspace says, 'Serial write value Temp = temperature in F. Serial write value Light = light level. Serial write value Runtime = millis (ms). Serial write value Note = CapTouchCounter. Serial write value Button = buttonCount.'
  1. Change the name of the file to SimpleUART, hit the save icon, and then flash this to your Circuit Playground Express.
  2. With the slide switch on the Circuit Playground Express to the right, you should be able to again play four octaves of the ‘C’ scale. Slide it to the left if you do not want it to play the scales moving forward.
  3. From a web browser, enter:
  4. Take a glance at this new Python code called
    1. This code first imports some needed Python library packages accessed through the Python Package Index[3], including:
      • serial, used to receive and transmit serial data
      • os, which will let us to run Linux commands and read data
      • sleep, which lets us run the time function
      • RPi.GPIO, the PyPI project specifically for the Raspberry Pi GPIO
    2. The code creates a variable called uart and connects it to the /dev/ttyUSB0 device. If you needed to change the USB port used for the Blue Unit Toolbox Trumpet Counterstory Player, keep this in mind. You’ll need to make that change again after downloading this file.
    3. A key addition is a new function, convert, that is created to change the Runtime from milliseconds to hours, minutes, and seconds.
    4. The last half is a “while True” FOREVER loop that reads in the five lines each time they are sent from the Circuit Playground Express. It fine tunes each of the lines to make them more readable and then prints them to standard out, which typically is a terminal window display of the Raspberry Pi.
    5. NOTE: An essential piece of the fine tuning is related to the “decode” process. In particular, the Circuit Playground Express sends lines of data encoded using . According to Wikipedia, “Unicode Transformation Format 8-bit is a variable-width encoding that can represent every character in the Unicode character set. It was designed for backward compatibility with ASCII and to avoid the complications of endianness and byte order marks in UTF-16 and UTF-32.”[4] is the American Standard Code for Information Interchange. It was the standard for US-based computers and the basic encoding scheme initially within the Internet Protocol. However, this limited usable character sets, something that plagues much of global Internet usage to this day.[5]
  5. Right click on the simple_uart5 programming code and save it as to your personal computer (if connecting to the Raspberry Pi using screen, PuTTY, or SSH) or to your Raspberry Pi (if using a keyboard, monitor, and mouse with the Raspberry Pi). Make sure to save it as a Python file with the .py extension, not with the default .txt extension.
    • If the file was saved to your personal computer, copy it over to your Raspberry Pi using the scp command.
    • If you have more than one USB device connected to your Raspberry Pi, you may need to edit the Python code using nano, to match the /dev/ttyUSB0 line to your exact USB.
  6. In a Raspberry Pi terminal window, type in:
  • pi@raspberrypi:~ $ python3

Once the program begins, you will see new sensor information printed to the terminal window every second. Try pressing different sensors and buttons to see the data output change. You can end the Python session at any time by hitting CTRL-C. The display will look something like this:

The Python script runs in the Unix terminal window, returning raw data from the Circuit Playground Express.

This may take some pair programming and failing forward to get up and running. Remember to work through the troubleshooting basics cycle to work from “not yet” to “yet”!

The cycle of troubleshooting: Troubleshooting includes observation of what you're sensing, thinking about what might be the reasons things are different from normal, planning a way to test possible causes, and acting upon your plan.

Key Takeaways

Microcontrollers are common in many of our everyday electronics, from computers to printers to microwaves to cars. Sometimes they only serve to sense device context and then control the motors running a device accordingly. Other times, sensor data is collected and passed on to other microcontrollers and to microcomputers. And sometimes microcontrollers collect data from other sensors first. The Circuit Playground Express has been designed first as an educational tool, but as we’ve seen first building the Toolbox Trumpet Counterstory Player and now in this exercise, it has a range of sensor capabilities that could be used as datasets informing actions for a range of information services.

What might you do next to remix this?

So far we’ve used the terminal window to view Python information. But since Python version 3, it is also possible to print this information as Hypertext Transfer Protocol (HTTP) server data instead of, or in addition to, a standard output like we’ve now sent to the terminal window. With the Python code and UART communications confirmed, let’s explore how this data can be made remotely available.

The Hypertext Transfer Protocol is a well-established, highly used TCP/IP-based client/server protocol that we’ll explore more formally in Rainbow Unit, Session 2. For now, consider that you make regular use of web browsers which perform a client role putting forward requests to associated servers using the same protocol. Today, web browsers are mostly used to access pages stored on HTTP servers by typing in an http:// or https://, followed by an Internet Protocol name associated with that server, and perhaps further subdirectory names on that server, each separated by another ‘/’ symbol, and finally the resource name at the end of the last ‘/’ symbol if needed. Together this creates a . The URL is a commonly used form of the more general Uniform Resource Indicator (URI), strings of characters used to unambiguously identify a particular resource. The first part of the URL states the protocol to be used. Web browsers actually support a number of different protocols, but we almost always make use of the HTTP protocol or the secure Hypertext Transfer Protocol, HTTPS. For the following exercises, the remainder of the http:// URL will include the Raspberry Pi’s IP address and a special port number we’ll define in the Python code to separate it from any other web servers that may be running on your local network.

Exercise: Using http to Remotely Monitor Sensor Information

For this exercise, we do not need to change anything on the Circuit Playground Express or with the TTL/USB cable connection to the Raspberry Pi. The focus instead is on the Raspberry Pi IP Address and the Python code that will be used to read the five lines of serial data sent once every second by the Circuit Playground Express using the TTL/USB cable.

  1. From a web browser, enter:
  2. Take a glance at this new Python code called This is pretty complex, and do not worry if it doesn’t make much sense at this time. Notes have been added, delineated using the comment character “#”. Doing a quick read of these comments might be helpful to just highlight key aspects of the Python code. Later, after running this Python code on the Raspberry Pi and then reading data through a web browser, come back and review it again.
  3. Right click on the programming code and save it as to your personal computer (if connecting to the Raspberry Pi using screen, PuTTY, or SSH) or to your Raspberry Pi (if using a keyboard, monitor, and mouse with the Raspberry Pi). Make sure it is not saved with a final .txt extension.
  4. This code will now need to be edited using a simple text editor on your laptop, or using nano on the Raspberry Pi: pi@raspberrypi:~ $ nano
    Whichever text editor you use, here are the changes that need to be made:
    • In the third section at the top of the code, note the host_name is configured to the IP address assigned to my home Raspberry Pi (more on connecting your Raspberry Pi to a Local Area Network (LAN) is provided in the backmatter of this textbook). The host_name variable will need to be changed after downloading the Python code to match the IP address you find when typing into the Raspberry Pi terminal window the following:
    • pi@raspberrypi:~ $ hostname -I
      The hostname -I command returns the IP address of the Raspberry Pi in the Unix terminal window.
      Also included in this section is a host_port. Think of a shipping port of call as an analogy. When arriving at a shoreline with designated docking ports for a boat or ship, a set of names or numbers are used. This is the same for the Internet Protocol. By default, HTTP uses port 80 and HTTPS uses port 443. Ports from 0 through 1023 are well-known system ports and are stricter than ports above this range. Port 8080 is actually a common number used for test web servers. The iSchool course for which this textbook is commonly used is IS401, and so 8401 is the chosen host_port listed here. But this can be changed, and indeed should be changed if the same Raspberry Pi is attempting to run multiple different web servers simultaneously.
    • If you have more than one USB device connected to your Raspberry Pi, you may now need also revise the /dev/ttyUSB0 line to an appropriate USB device other than 0.
  5. Save the changes to the Python code.
    • If was edited using nano on the Raspberry Pi, use CTRL-O to write out the file keeping it the same name, then CTRL-X to exit nano.
    • If was edited on your personal computer, copy it over to your Raspberry Pi next.
  6. With the Python code tweaked to match your IP address and possibly your /dev/ttypUSB assignment, type the following in a Raspberry Pi terminal window:
  • pi@raspberrypi:~ $ python3
  1. In a web browser located on the same local network as your Raspberry Pi, type in your Raspberry Pi’s IP address, followed by :8401, like this:

This is the most complex piece of programming code we’ve worked with yet. It includes changes needed within Python to match it with the IP address of your Raspberry Pi. For some, this may be the first time you’ve edited Python. You may have been using the Raspberry Pi in Graphical User Interface mode with a keyboard, mouse, and monitor and thus it might be the first time you’ve had to work with the IP address of the Raspberry Pi.

In addition, many new concepts related to networking are just starting to be introduced. In all, there are plenty of “fail forward” opportunities to advance a growth mindset. Maybe too many for the time being, in which case “yet enough” might be working collaboratively with another person to walk one of you through this exercise on one Raspberry Pi.

But I would encourage you to spend at least 45 minutes or so working to fail forward on each Raspberry Pi available, comparing and contrasting what works and what doesn’t work as a community of practice.

When you’re ready to take a closer look, highlights of the code include:In addition to several other Python libraries, the code imports the http.server part of the base Hypertext Transfer Protocol request handler and server libraries.The core part of the Python code is the class BaseHTTPRequestHandler. In Python, “classes provide a means of bundling data and functionality together.”[6] BaseHTTPRequestHandler “is used to handle the HTTP requests that arrive at the server. By itself, it cannot respond to any actual HTTP requests; it must be subclassed to handle each request method (e.g. GET or POST).”[7]In this case, do_HEAD() sends the headers it sends for a typical GET request sent from a HTTP client, including a 200 OK response and a content type ‘text/html’ noting text and/or is being sent back to the client.The do_GET() does the lion’s share of the work setting up a dynamic HTML page. It can do this because a special implementation of BaseHTTPRequestHandler is being used for reading data from and controlling GPIO of a Raspberry Pi — note the Import RPi.GPIO at the top of the file.At the bottom of the do_GET() function, you’ll note a wfile.write statement, written in the stated html.format, encoded in utf-8. Within the html.format portion of this statement, there are seven items providing data to be integrated into the seven {} tags above, in order from top to bottom. So the “temp” data is collected using the vcgencmd, that is, the Raspberry Pi VideoCore GPU command line utility. The five Circuit Playground Express data items are read next through the USB to TTL serial port, and finally an empty status line, something currently unused.The last lines of the Python code are the location where the server hangs out waiting for client requests before going into action with the class BaseHTTPRequestHandler code.The html text within the code includes a statement:

<meta http-equiv="refresh" content="1">

Many web browsers know what it means and are set up by default to follow this meta statement to refresh the content with a new request to the server every second. The terminal window will note who placed the request for information, when the request was placed, and the do_HEAD response provided, while the web server will show the do_GET response provided, as shown below:

The webpage for the Raspberry Pi web server runs in the Google Chrome web browser, displaying the message 'Welcome to my Raspbery Pi.' In a PowerShell terminal, a series of messages display the IP address of the web server (, the timestamp, and the HTTP protocol followed ('GET /favicon.ico HTTP/1.1 200 -').

A link stating “Click here to refresh dataset” and javascript refresh script is also provided in the HTML to facilitate manual refreshes of the data, in case a web browser does not follow the meta instructions.

Key Takeaways

The Hypertext Transfer Protocol (HTTP) is a widely used client/server protocol. For most, you’ll know this through HTTP application as a general-purpose server in which many different parent and child web pages are located on a single web server. This textbook is a gathering of many individual web pages located on one of those general-purpose servers. There are other Illinois Open Publishing Network “Windsor & Downs” books, and also a number of “Publishing Without Walls” books and “IOPN Journals” all located on this general purpose web server.

In this exercise, though, we’re running a special-purpose, Python-based HTTP server on a microcomputer and setup to provide data it collects both from its own hardware, and data provided over a serial connect from a microcontroller as a single web page. But as is the case with the majority of HTTP-provided data, it is sent using the Hypertext Markup Language (HTML), the standard for web pages.[8] An important takeaway is the distinction between HTML standard and the HTTP protocol. Both are Internet Protocol-based. But while standards serve as guidelines that can or should be followed, protocols serve as rules defining exactly how data is exchanged and the expected behavior to be followed within this change. You can put anything into an HTML page that you want and it will be sent to the requester whatever is in there. But if it is something outside of the standard, it may be ignored or even lead to special or bad behavior if it is not following the standard. But if HTTP does not follow the protocol to the tee, it is unlikely to travel the length of the Internet and effectively carry through with communication between the client and the server devices using this protocol.

Within an object-oriented programming language, a collection of data variables are acted upon using defined functions that are brought together as an object. A class then serves as the blueprint for that object. In this exercise, the class BaseHTTPRequestHandler brought together two functions, do_HEAD and do_GET, each beginning with the Python function keyword “def”. The do_GET() method, or function, implements the standard GET method of HTTP/1.1 used to retrieve whatever information is identified by the Request-URI. The do_HEAD() method, on the other hand, MUST NOT return a message-body but rather the metainformation continued in the HTTP headers. This is different from the <head></head> of HTML standard, which is instead meta-information as defined within the HTTP protocol. For more, take a look at the formal protocol definitions page from W3C, the World Wide Web Consortium.

Currently MakeCode on the Circuit Playground Express only supports the writing of data using one of the serial write blocks, thereby providing data to the other side of the UART connection. It does not support the serial read blocks. Otherwise we could enter the data into variables and use those, for instance, to set LED pixels to specified colors. But think back to the Orange Unit’s Coding Electronics chapter where we used Python to read the two momentary switch push buttons and turn on or off associated LEDs accordingly.

Take a minute to review the Orange Unit Python code called we previously downloaded from and ran using the Raspberry Pi terminal window to type in:


A diagram of programmed circuits on the breadboard, which is connected to the GPIO of the Raspberry Pi.

Exercise: Using HTTP to Remotely Control LEDs

As we enter into this last exercise, let’s consider how we might make use of the Python class BaseHTTPRequestHandler on the Raspberry Pi to not only provide regularly updated Circuit Playground Express data, but also information regarding which LED is currently running on the breadboard based on the status of the Momentary Switch push buttons just reviewed above. Further, since we have some other LEDs available, let’s add in an additional red, green, and blue LED set that we can set up to remotely turn on and off, using the same Python HTTP server program. While this will bring together two “things” on one Raspberry Pi, this also provides a potential launchpad for considering ways different microcontrollers and microcomputers could ultimately further be brought together to create a range of local “Internet of Things” devices.

Step 1: Adding LEDs to the Breadboard

Before we get started setting up the Python code, look through the following Fritzing diagrams to consider what you have on hand to complete this exercise. The primary objective is to connect the cathode of a blue LED to pin 13 of the GPIO, a green LED to pin 19 of the GPIO, and a red LED to pin 26 of the GPIO.

A diagram of the Circuit Playground Express, connected by UART to the Raspberry Pi, connected to the breadboard via the Cobbler. On the breadboard, red, green, and blue sequins connect using male to alligator clip wires to form a circuit from the GPIO pins back to ground.
A diagram of the Circuit Playground Express, connected by UART to the Raspberry Pi, connected to the breadboard via the Cobbler. On the breadboard, red, green, and blue LEDs, resistors, and jumper wires form a circuit from the GPIO pin back to ground.
A diagram of the Circuit Playground Express, connected by UART to the Raspberry Pi, connected to the breadboard via the Cobbler. On the breadboard, a diffused RGB (tri-color) LED with common anode to 3V3 cathodes to GPIO pins 13, 19, and 26 via resistors.

  • Option 1: The sequins are integrated circuits that include their own resistors, so no additional resistors are needed. Six male to alligator clip wires are needed. Connect the positive, anode side of each to the 3.3 Volt rail. Connect the negative, cathode side of each to the appropriate pin.
  • Option 2: The 10mm red, green, and blue LEDs are connected opposite to the ones above, with the resistors being connected to the cathode side of each LED. As before, the other sides of the resistors are connected to the appropriate pins on the GPIO. The anode side of each LED can be directly connected to the 3.3 volt rail.
  • Option 3: The diffused RGB LED is listed in the Introduction as a possible extra to the kit. What makes this especially fitting for this exercise is that the three different colors can provide a range of seven different shades of light, similar to the seven different Hertz, or notes, the three bits of the Toolbox Trumpet at a given C-scale. One leg of the RGB LED is longer than the other three, and is the common anode leg that receives the voltage input that is then provided to each of the three different embedded LEDs within. Connect this to the 3.3 volt rail. The two legs on one side of the anode are the Green and Blue cathode legs, while the single leg on the other side of the anode is the Red cathode leg.

Whichever LED setup you choose, before connecting the cathode leg of each LED/Sequin to the appropriate GPIO pin, you can connect it to the blue ground rail, at which time it should turn on.

Step 2: Setting Up the New Python Code

With the three new LEDs, each connected to a different GPIO port, available, this final Python program is a remix of the simple_uartWebserverCPE. A new table has been added to the HTML portion of def do_GET from which a selection can be made regarding which of the three LEDs should be on, and which should be off. And below that, additional variables have been set up to read from, and write to, the appropriate GPIO pins.

  1. From a web browser, enter:
  2. As before, take a quick glance at this new Python code called Much of it is taken directly from the program. And as before, after downloading this, you will need to edit the Python file to change the “host_name” from, the local IP Address of my Raspberry Pi at my home office, to be whatever IP address you were assigned on your local network. The file is much longer, though, because of the new HTML table and then the new series of “If…Then…Else” conditionals, one to provide an edited output of the Circuit Playground Express data, the other to interact with the GPIO pins and edit associated variables.
  3. Right click on the programming code and save it as to your personal computer (if connecting to the Raspberry Pi using screen, PuTTY, or SSH) or to your Raspberry Pi (if using a keyboard, monitor, and mouse with the Raspberry Pi). Make sure it is not saved with a final .txt extension.
  4. This code will now need to be edited using:
    • a simple text editor on your laptop, or;
    • using nano on the Raspberry Pi
      pi@raspberrypi:~ $ nano
  • Whichever text editor you use, here are the changes that need to be made:
    • ALL: Change the host_name to match the IP address assigned to your Raspberry Pi as seen in the hostname command, or as used to ssh into your Raspberry Pi.
    • If you have more than one USB device connected to your Raspberry Pi, you may now need also revise the /dev/ttyUSB0 line to an appropriate USB device other than 0.
    • ALL: save the changes you just made.
      • If was edited using nano on the Raspberry Pi, use CTRL-O to write out the file keeping it the same name, then CTRL-X to exit nano.
      • If was edited on your personal computer, copy it over to your Raspberry Pi next.
  1. Before going to the next step, be sure used in the previous exercise is not still running as it is already using the assigned port number for its own HTTP server. To stop a program running on the Linux command line, you typically will type:
  • pi@raspberrypi:~ $ CTRL-CWhere CTRL- indicates for you to press and hold down the control key on your keyboard while typing in the additional key, which in this case is the letter ‘c’.
  1. In one window, if it isn’t already running restart by typing in:
  • python3
  1. With the Python code tweaked to match your IP address and possibly your /dev/ttypUSB assignment, in a second Raspberry Pi terminal window, type in:
  • pi@raspberrypi:~ $ python3
  1. In a web browser located on the same local network as your Raspberry Pi, type in:
  •, replace the IP address above with your Raspberry Pi’s.

You should now see something like the following:

The Raspberry Pi is connected by the Cobbler to the breadboard, which is connected by alligator clips to the Circuit Playground Express. Two fingers press down on the buttons of the Circuit Playground Express.

The webpage for the Raspberry Pi web server runs in the Google Chrome web browser, displaying the message 'Welcome to my Raspbery Pi, Your Remote Control Choices,' with a table of links, and statistics about the Circuit Playground Express. The color violet is selected. Two PowerShell terminal windows are open. The first displays a serial console connection to the Raspberry Pi, running the Python code. The second displays a series of messages display the IP address of the web server (, the timestamp, and the HTTP protocol followed ('GET /favicon.ico HTTP/1.1' 200 -').

Key Takeaways

In this exercise, we have revisited an exercise from the Orange Unit in which Python code was used to create a programmable circuit allowing us to selectively turn on and off LEDs using Momentary Switch push buttons. We have continued to use a MakeCode Toolbox Trumpet program on the Circuit Playground Express which allows us to play four octaves of the C-Scale. And finally we expanded the Python code from the previous exercise to both report on data from the Circuit Playground Express and also from the Raspberry Pi GPIO, and also add in the ability to remotely control another red, green, and blue LED set.

Pause to look again at the two images taken to display the target outcome of this exercise. Now that these are set up and working properly, consider the following probe questions:

  • How many different devices are now playing a role as tools within this third exercise?
  • How many different computer programs are now playing a role facilitating the use of these tools?
  • Which tools could be used independent of the other tools shown in the images? Which ones must be used together to work? Which ones cannot work fully independently, but could be used through slight adjustments, for instance, by just being provided a separate power source?
  • Which ones now require access to the Internet periodically, or continuously, to function effectively? Consider the Internet not as the local network, even though it works using the Internet Protocol, but rather the connection to the global Internet provided by your Internet Service Provider.
  • Who shaped the different tools, including the electronics and computer programs used to create these tools? How does this shaping go on to shape your use of them?

Wrap Up

As we’ve worked through Session One, we’ve worked to demystify what it means when someone says a thing is an Internet of Things, or Smart device. We’ve worked to unpack what is actually within these devices, and also what is essential for them to work together. The goal is for this to help us to see that IoT devices can often stand separately and work independently. But as they are brought together on a local network, the data can start being combined to further influence the monitoring and activity of these interrelated devices. Also, as we’ve seen here, a local microcomputer can be set up to collect the data from multiple other datasets separately collected on devices and consolidated into a single output.

From here, consider that both the Raspberry Pi and Circuit Playground Express themselves can collect data from multiple worker devices as a parent using the I2C serial data transmission protocol. When Circuit Playground Express is programmed using Python or Arduino, this could include both input and output data with a range of remote microcontrollers and integrated circuit sensors and motors, with data being stored in a file instead of, or in addition to, sending it to the Raspberry Pi using the UART serial communications protocol. Likewise, the Raspberry Pi can both provide data dynamically to a web browser and also store this data in a file or database. And while our programs have been used to provide a consistent unconditioned stimulus and response pattern, it is possible that through the use of machine learning algorithms, this can be expanded to create conditionals to reshape stimulus and response patterns. All of this can readily be done without Internet connectivity using local networking technologies.

But it’s also important to note that there’s the Internet of Things and there’s the Bitnet of Things as differentiated by Neil Gershenfeld and his colleagues. If the Raspberry Pi serves exclusively or primarily as a storage center for data, this is more like a centralized Bitnet of Things. Even if this centralized system facilitates remote control of devices, it has not yet moved to being an Internet of Things device, especially if each microcontroller/microcomputer device with which it might communicate remains separate from all other devices within its arena.

As an example, I found it increasingly important to purchase a window air conditioner for our home woodshop given the rising nighttime temperatures, increased humidity, and the negative impacts this was having on the metal tools and wood used in our carpentry projects. This week I purchased a Toshiba Smart Wi-Fi Window Air Conditioner with Remote and ENERGY STAR. In setting it up, I was able to use the easy to use touch controls. What about some of the other methods for working with the air conditioner specified using the terms Smart, Wi-Fi, and Remote? Toshiba clarifies the Remote Control as a now standard radio frequency handheld remote used within the same room. The Wi-Fi, on the other hand, requires a connection to the Local Area Network, thereby facilitating communications with the associated smartphone app and with voice controlled using Amazon Skill. Toshiba has helpfully clarified that their use of the term smart indicates the air conditioner, like our remotely controlled LEDs, can interface with smartphones. And while the Amazon Alexa Skills system does incorporate machine learning and narrow artificial intelligence (AI for a specific task), these are not incorporated within the air conditioner to provide ongoing engineering of the auto settings.

This is the concept behind the Bitnet of Things for Neil Gershenfeld and others.

What might be the alternative pathway in which the air conditioner was integrated within an Internet of Things workshop? The table saw, bandsaw, planers, chop saw, woodlathe, air compressor, dust collector, and various other mechanical tools and also the wood resources would include sensors set up as Internet of Things devices. The dust collector, air compressor, and air conditioner would monitor the saws, planers, and lathes to detect usage and performance levels. These would be used to adjust settings on the climatic and air quality standards within the space to increase performance and longevity of machine, human, and more-than-human alike. In part, this would be done through integrated machine learning that worked not only individually on each of the many sensors and controllers, but through end-to-end strategic learning to recognize the best adjustments given the different contexts and current requirements. After all, the woodshop is a very different space when it is also being used to raise a new gathering of soon-to-lay-egg chicks, or when it is used by my students to design, cut, and build computer tables, or when it is used by my family to build gifts, sometimes in rapid succession.

This is the concept behind the Internet of Things. Machine learning moves from a centralized command and control to each of the various tools that now have as part of the construction electronic sensors, servomotors, and other controllers. These tools then work in an artificial community of practice to achieve objectives the algorithms on each individual device could not do alone.

It is not essential for there to be Internet access, although sometimes it might be useful for there to be. For instance, if we were to configure the home router, which is provided a public IP address, to forward port 8401 requests to the private IP address of the Raspberry Pi, then web browsers around the world could choose the LED color! If done in this way, the Internet is not needed to collect and analyze the data and adjust algorithms accordingly, but instead is used to provide additional data as helpful.

And there are times when it is helpful to send data to remote databases, HTTP servers, and other systems, either as the primary server array for storing and consolidating information, or as a secondary location in addition to the primary local server. This will be the focus of Session Two of the Rainbow Unit.

For now, this and the previous exercise provide baseline examples of the broader framework used for many Internet of Things devices. But it also provided some starting points that you could use to build your own Internet of Things devices right now. For those wanting to dig deeper into the technical work of building Internet of Things devices, you may want to watch further episodes in the series, including:

Comprehension Check

  1. Read the full video transcript on Adafruit’s website.
  2. Read the full video transcript on Adafruit’s website.
  3. Also known as PyPI, pronounced like “pie-pea-eye.” Despite the shared “PI,” it is not specifically Raspberry Pi-related.
  4. “UTF-8” in Wikipedia, July 20, 2020, For more resources on UTF-8, see
  5. Endianness defines the ordering of bytes of a word of digital data, with big-endian-based and little-endian-based computer architectures ordering bytes in storage in two significantly different ways. Today’s major personal computer providers use the little-endian format.
  6. “9. Classes — Python 3.8.4 Documentation,” accessed July 20, 2020,
  7. “Http.Server — HTTP Servers — Python 3.8.4 Documentation,” accessed July 20, 2020,
  8. A tutorial for HTML is available from


Icon for the Creative Commons Attribution-ShareAlike 4.0 International License

A Person-Centered Guide to Demystifying Technology Copyright © 2020 by Copyright © 2020 Martin Wolske. 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. is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License, except where otherwise noted.

Share This Book