© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
C. BellBeginning MicroPython with the Raspberry Pi Picohttps://doi.org/10.1007/978-1-4842-8135-2_2

2. Introducing MicroPython

Charles Bell1  
(1)
Warsaw, VA, USA
 

Now that we have learned more about the Raspberry Pi Pico and saw a demonstration of how to connect to it from our PC, it is time to learn more about MicroPython – how we can get started, how it works, and examples of what you can do with your own Pico.

Learning MicroPython is very easy even for those who have not had any programming experience. Indeed, all you need to learn MicroPython is a bit of patience and a little time to get used to the syntax and the mechanisms unique to working with MicroPython, the Pico, and the electronics. As we will see, there is a lot you can do with just a little knowledge.

In this chapter, we will learn more about MicroPython including an overview of how to get started. The examples in this chapter are intended to give you a taste of what you can do rather than a detailed tutorial. That said, I encourage you to attempt the examples for practice. We will see a detailed tutorial for programming MicroPython in Chapter 3 and a deeper dive into the software libraries for lower-level hardware support in Chapter 4.

Let’s start with a look at what MicroPython is including why it was created and how to get started.

Note

Since MicroPython runs on many boards, I use the term “boards” to mean any board that runs MicroPython, which includes the Pico.

Getting Started

The use of the Python language for controlling hardware has been around for some time. Users of the Raspberry Pi, pcDuino, and other low-cost computers and similar boards have had the advantage of using Python for controlling hardware. In this case, they used full versions of the Python programming language on the native Linux-based operating system.

While these boards made it possible for those who wanted to develop electronics projects, it required users to buy the board as well as peripherals like a keyboard, mouse, and monitor. Not only that, but users also had to learn the operating system. For those not used to Linux, this can be a challenge in and of itself.

The vision for MicroPython was to combine the simplicity of learning Python with the low cost and ease of use of microcontroller boards, which would permit a lot more people to work with electronics for art and science projects. Beginners would not have to learn a new operating system or learn one of the more complex programming languages. MicroPython was the answer. Figure 2-1 shows the MicroPython logo in the form of a sticker from Adafruit.
Figure 2-1

MicroPython logo skill badge (courtesy of adafruit.com)

That’s pretty cool, isn’t it? It’s a snake (a python) on an integrated circuit (chip). You can order this nifty MicroPython sticker (www.adafruit.com/products/3270). I recommend getting one of these and displaying it proudly when you finish the book.

Origins

MicroPython1 was created and is maintained by Damien P. George, Paul Sokolovsky, and other contributors. It was designed to be a lean, efficient version of the Python 3 language and installed on a small microcontroller. Since Python is an interpreted language and thus slower (in general) than compiled languages, MicroPython was designed to be as efficient as possible so that it can run on microcontrollers that normally are slower and have much less memory than a typical personal computer.

Compiled Vs. Interpreted

Compiled languages use a program, called a compiler, to convert the source code from a human-readable form to a binary executable form. There are a few steps involved in this conversion, but, in general, we take source code and compile it into a binary form. Since it is in binary form, the processor can execute the statements generated directly without any additional steps (again, in general).

Interpreted languages, on the other hand, are not compiled but instead are converted to a binary form (or an intermediate binary form) on the fly with a program called an interpreter. Python 3 provides a Python executable that is both an interpreter and a console that allows you to run your code as you type it in. Python programs run one line of code at a time starting at the top of the file.

Thus, compiled languages are faster than interpreted languages because the code is prepared for execution and does not require an intermediate, real-time step to process the code before execution.

Another aspect is microcontroller boards like the Arduino and similar boards require a compilation step that you must perform on your computer and load the binary executable onto the board first. In contrast, since MicroPython has its interpreter running directly on the hardware, we do not need the intermediate step to prepare the code; we can run the interpreted language directly on the hardware!

This permits hardware manufacturers to build small, inexpensive boards that include MicroPython on the same chip as the microprocessor (typically). This gives you the ability to connect to the board, write the code, and execute it without any extra work.

You may be thinking that to reduce Python 3 to a size that fits on a small chip with limited memory, the language is stripped down and lacking features. That can’t be further than the truth. In fact, MicroPython is a complete implementation of the core features of Python 3 including a compact runtime and interactive interpreter. There is support for reading and writing files, loading modules, interacting with hardware such as GPIO pins, error handling, and much more. Best of all, the optimization of Python 3 code allows it to be compiled into a binary requiring about 256K of memory to store the binary and run with as little as 16K of RAM.

However, there are a few things that MicroPython doesn’t implement from the Python 3 language. The following sections give you an idea of what you can do with MicroPython and what you cannot do with MicroPython.

MicroPython Features

The biggest feature of MicroPython is, of course, it runs Python. This permits you to create simple, efficiently specified, and easy-to-understand programs. That alone, I think, is its best advantage over other boards like the Arduino. The following lists a few of the features that MicroPython supports. We will see these features in greater detail throughout this book:
  • Interactive interpreter: MicroPython boards have built in a special interactive console that you can access by connecting to the board with a USB cable. Recall from Chapter 1, the console is called a read-evaluate-print loop (REPL) that allows you to type in your code and execute it one line at a time. It is a great way to prototype your code or just run a project as you develop it.

  • Python standard libraries: MicroPython also supports many of the standard Python libraries. In general, you can expect to find MicroPython supports more than 80% of the most commonly used libraries. These include parsing JavaScript Object Notation (JSON),2 socket programming, string manipulation, file input/output, and even regular expression support.

  • Hardware-level libraries: MicroPython has libraries built-in that allow you to access hardware directly either to turn on or off analog pins, read analog data, read digital data, and even control hardware with pulse-width modulation (PWM) – a way to limit power to a device by rapidly modulating the power to the device, for example, making a fan spin slower than if it had full power.

  • Extensible: MicroPython is also extensible. This is a great feature for advanced users who need to implement some complex library at a low level (in C or C++) and include the new library in MicroPython. Yes, this means you can build in your own unique code and make it part of the MicroPython feature set.

To answer your question, “What can I do with MicroPython?”, the answer is quite a lot! You can control hardware connected to the MicroPython board, write code modules to expand the features of your program storing them for later retrieval (just like you can in Python on a PC), and much more. The hardware you can connect to include turning LEDs on and off, drive servos, read sensors, and even display text on LCDs. Some boards also have networking support in the form of WiFi radios. Just about anything you can do with the other microcontroller boards, you can do with a MicroPython board.

However, there are a few limitations to running MicroPython on the chip.

MicroPython Limitations

The biggest limitation of MicroPython is its ease of use. The ease of using Python means the code is interpreted on the fly. And while MicroPython is highly optimized, there is still a penalty for the interpreter. This means that projects that require a high degree of precision such as sampling data at a high rate or communicating over a connection (USB, hardware interface, etc.) may not run fast enough. For these areas, we can overcome the problem by extending the MicroPython language with optimized libraries for handling the low-level communication.

MicroPython also uses a bit more memory than other microcontroller platforms such as the Arduino. Normally, this isn’t a problem but something you should consider if your program starts to get large. Larger programs that use a lot of libraries could consume more memory than you may expect. Once again, this is related to the ease of use of Python – another price to pay.

Finally, as mentioned previously, MicroPython doesn’t implement all the features of all the Python 3 libraries. However, you should find it has everything you need to build IoT projects (and more).

Are My Python Skills Applicable To Micropython?

If you’ve already learned how to program with Python, you may be expecting to see something that stands out as different or even odd about MicroPython. The good news is your Python skills are all you need to work with MicroPython. Indeed, MicroPython and Python use the same syntax; there isn’t anything new to learn. As you will see in the next few chapters, MicroPython implements a subset of Python libraries but still is very much Python.

What Does MicroPython Run On?

Due to the increasing popularity of MicroPython, there are more options for boards to run MicroPython being added regularly. Part of this is from developers building processor- and platform-specific compiled versions of MicroPython that you can download and install on the board. This is how the Raspberry Pi Pico works.

One Micropython, Many Boards

There are other microcontroller and microprocessor boards that run MicroPython natively (installed at the factory) or can be loaded with MicroPython binaries, for example, the pyboard (https://micropython.org/), which was the first MicroPython board created by the implementors of MicroPython. There is also the WiPy (https://pycom.io/), which is an excellent IoT board. There are also versions of the Espressif (ESP) boards and Arduino that run MicroPython.

However, some of the other boards use a slightly different mix of MicroPython libraries because some MicroPython boards have different hardware. Take care when studying online examples to ensure you are referencing a generic MicroPython example or one tailored to the Pico. We will focus exclusively on the Pico in this book.

Next, let’s talk about using Python on our PC for experimenting with learning the language.

Experimenting with Python on Your PC

Since MicroPython is Python (just a bit scaled down for optimization purposes), you can run Python on your PC and experiment with the language. I recommend loading Python on your PC even if you already have a MicroPython board. You may find it more convenient to try out things with your PC since you can control the environment better. However, your PC won’t be able to communicate with electronic components or hardware like the MicroPython boards, so while you can do a lot more on the PC, you can’t test your code that communicates with hardware. But you can test the basic constructs such as function calls, printing messages, and more.

So, why bother? Simply, using your PC to debug your Python code will allow you to get much of your project complete and working before trying it on the MicroPython board. More specifically, by developing the mundane things on your PC, you eliminate a lot of potential problems debugging your code on the MicroPython board. This is the number one mistake novice programmers make – writing an entire solution without testing smaller parts. It is always better to start small and test a small part of the code at a time adding only those parts that have been tested and shown to work correctly.

All you need to get started is to download and install Python 3 (e.g., Python 3.9.6 is the latest, but new versions become available periodically). The following sections briefly describe how to install Python on various platforms. For specific information about platforms not listed here, see the Python wiki at https://wiki.python.org/moin/BeginnersGuide/Download.

Caution

There are two versions of Python available – Python 2 and Python 3. Since MicroPython is based on Python 3, you will need to install Python version 3, not Python version 2.

Fortunately, most computers today come with Python installed. If you are not sure, open a terminal window (command window) and type the following command:
$ python –version
Python 3.9.6

If you get a result similar to what is shown earlier, you’ve got what you need. If not, you should install Python on your PC. Some computers may have both Python 2 and 3 installed. In this case, you may see a different version than what is shown earlier.

If you saw a version like Python 2.7.X, there is still a chance you have Python 3 on your machine. Some systems have both Python 2 and Python 3 installed. To run Python 3, use the following command:
$ python3

If Python 3 is not installed or it is an older version, use the following sections to install Python on your system. You should always install the latest version. You can download Python 3 from www.python.org/downloads/.

Installing Python 3 on Windows 10

Most Windows machines do not include Python, and you must install it. You can download Python 3 for Windows from www.python.org/downloads/windows/. You will find the usual Windows installer options for 32-bit and 64-bit versions as well as a web-based installer and a .zip format. Most people will use the Windows installer option, but if you have advanced needs to install Python manually, you can use the other options.

Once you download Python, you can launch the installer. For example, on my Windows 10 machine, I downloaded the file under the link named Latest Python 3 Release – Python 3.9.6. If you scroll down, you can find the installer you want. For example, I clicked the installer for Windows 64-bit machines. This downloaded a file named python-3.9.6-amd64.exe, which I located in my Downloads folder and executed by double-clicking the file.

Like most Windows installer installs, you can step through the various screens agreeing to the license, specifying where you want to install it, and finally initiating the install. Figure 2-2 shows an example of the installer running.
Figure 2-2

Installing Python 3.9.6 on Windows 10

Tip

If you get stuck or need more detailed instructions, see the excellent article at How-To Geek: www.howtogeek.com/197947/how-to-install-python-on-windows/.

Once the installation is complete, you can try the test in the previous section to verify the installation. If you do not modify your PATH variable, you may need to use the Python console shortcut on the start menu to launch the console.

In fact, if you run the installation and you cannot get Python to launch, you can fix this problem by running the installer again. When you launch the installer a subsequent time, you will be prompted on how to proceed. Click the Modify option as shown in Figure 2-3.
Figure 2-3

Modify Python 3.9.6 installation on Windows 10

On the next screen, ensure the pip option is chosen and click Next as shown in Figure 2-4. Pip is a special Python package installer that you will need to use to install additional Python libraries.
Figure 2-4

Select Optional Features for Python 3.9.6 install on Windows 10

On the next screen, ensure there are checkmarks for creating shortcuts and adding the Python command to the environment variables as shown in Figure 2-5.
Figure 2-5

Select Advanced Options for Python 3.9.6 install on Windows 10

Installing Python 3 on macOS

If you are using macOS, you probably have Python installed since most releases of macOS install Python by default. However, if you were not able to run the Python version command earlier or it wasn’t the correct version, you can still download the latest Python 3 from the Python website (www.python.org/downloads/mac-osx/). You will find several versions, but you should download the latest version available that matches your hardware. You will find an Intel-based installer and a universal installer. If in doubt, try the universal installer.

Once you download Python, you can launch the installer. For example, on my iMac, I downloaded the latest Python 3 file under the link named Latest Python 3 Release – Python 3.9.6. If you scroll down, you can find the installer you want. For example, I clicked the installer for Intel machines. This downloaded a file named python-3.9.6-macosx10.9.pkg, which I located in my Downloads folder and executed.

Like most installers, you can step through the various screens agreeing to the license, specifying where you want to install it, and finally initiating the install. Figure 2-6 shows an example of the installer running.
Figure 2-6

Installing Python 3.9.6 on macOS

Note

Depending on which version of macOS you are running, and how your security settings are set, you may need to change them to run the installer since it is not signed by an identified developer. See the Security & Privacy panel in your System Preferences.

Once the installation is complete, you can try the test in the previous section to verify the installation.

Installing Python 3 on Linux

If you are using Linux, the way you install Python will vary based on the platform. For instance, Ubuntu uses apt-get commands, while other distributions have different package managers. Use the default package manager for your platform to install Python 3.6 (or later).

For example, on Debian or Ubuntu, we install the Python 3.9 package using the following commands. The first command updates the packages to ensure we have the latest package references. The second command initiates a download of the necessary files and installs Python:
$ sudo apt-get update
$ sudo apt-get install python3.9

Once the installation is complete, you can try the test in the previous section to verify the installation.

Running the Python Console

Now let’s run some tests on our PC. Recall we can open a Python console by opening a terminal window (command prompt) and entering the command python (or python3 depending on your installation).

Once you see the prompt, enter the following code at the prompt (>>>). This code will print a message to the screen. The at the end is a special, nonprinting character that issues a carriage return (like pressing ENTER) to move to a new line.
print ("Hello, World!")
When you enter this code, you will see the result right away. Recall the interpreter works by executing one line of code at a time – each time you press Enter. However, unlike running a program stored in a file, the code you enter in the console is not saved. The following shows an example of running the Python console on Windows 10. Notice I typed in a simple program – the quintessential “Hello, World!” example:
C:> python –version
Python 3.9.6
C:> python
Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello, World!")
Hello, World!
>>> quit()
C:>
To quit the console, enter the code quit() as shown earlier. You can also enter the command help() to start the Python help utility. Here, you can enter different commands to get help on Python. For example, at the help prompt, you can type the topics command to get a quick overview of the commands available to use in the interpreter as shown in Listing 2-1. You can press CTRL+C to exit the help utility.
>>> help()
Welcome to Python 3.9's help utility!
If this is your first time using Python, you should definitely check out
the tutorial on the Internet at https://docs.python.org/3.9/tutorial/.
Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules.  To quit this help utility and
return to the interpreter, just type "quit".
To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".
help> topics
Here is a list of available topics.  Enter any topic name to get more help.
ASSERTION           DELETION           LOOPING        SHIFTING
ASSIGNMENT          DICTIONARIES       MAPPINGMETHODS SLICINGS
ATTRIBUTEMETHODS    DICTIONARYLITERALS MAPPINGS       SPECIALATTRIBUTES
ATTRIBUTES          DYNAMICFEATURES    METHODS        SPECIALIDENTIFIERS
AUGMENTEDASSIGNMENT ELLIPSIS           MODULES        SPECIALMETHODS
BASICMETHODS        EXCEPTIONS         NAMESPACES     STRINGMETHODS
BINARY              EXECUTION          NONE           STRINGS
BITWISE             EXPRESSIONS        NUMBERMETHODS  SUBSCRIPTS
BOOLEAN             FLOAT              NUMBERS        TRACEBACKS
CALLABLEMETHODS     FORMATTING         OBJECTS        TRUTHVALUE
CALLS               FRAMEOBJECTS       OPERATORS      TUPLELITERALS
CLASSES             FRAMES             PACKAGES       TUPLES
CODEOBJECTS         FUNCTIONS          POWER          TYPEOBJECTS
COMPARISON          IDENTIFIERS        PRECEDENCE     TYPES
COMPLEX             IMPORTING          PRIVATENAMES   UNARY
CONDITIONAL         INTEGER            RETURNING      UNICODE
CONTEXTMANAGERS     LISTLITERALS       SCOPING
CONVERSIONS         LISTS              SEQUENCEMETHODS
DEBUGGING           LITERALS           SEQUENCES
help>
You are now leaving help and returning to the Python interpreter.
If you want to ask for help on a particular object directly from the
interpreter, you can type "help(object)".  Executing "help('string')"
has the same effect as typing a particular string at the help> prompt.
>>>
Listing 2-1

Getting Help in the Python Interpreter

While that demonstrates running Python from your PC, it is not that interesting. Let’s see something a bit more complicated.

Running Python Programs with the Interpreter

Suppose your project required you to save data to a file or possibly read data from a file. Rather than try and figure out how to do this on your MicroPython board, we can experiment with files on our PC!

In the next example, I write data to a file and then read the data and print it out. Don’t worry too much about understanding the code – just read through it – it’s very intuitive. The with statement allows us to open a file and operate on it inside the code block and then automatically close it for us when it exits the code block. Listing 2-2 shows the code for this example. I used a text editor and saved the file as file_io.py.
# Step 1: Create a file and write some data
with open("log.txt", "w") as new_file:    # use "write" mode
    new_file.write("1,apples,2.5 ")   # write some data
    new_file.write("2,oranges,1 ")    # write some data
    new_file.write("3,peaches,3 ")    # write some data
    new_file.write("4,grapes,21 ")    # write some data
# Step 2: Open a file and read data
with open("log.txt", "r") as old_file:  # use "read" mode
    # Use a loop to read all rows in the file
    for row in old_file.readlines():
        columns = row.strip(" ").split(",") # split row by commas
        print(" : ".join(columns))  # print the row with colon separator
Listing 2-2

File I/O Example

I saved the code to a file to show you how you can execute your Python scripts using the Python interpreter using the following command:
python ./file_io.py
Listing 2-3 shows the results of running the script.
$ python ./file_io.py
1 : apples : 2.5
2 : oranges : 1
3 : peaches : 3
4 : grapes : 21
Listing 2-3

Output for the File I/O Example

Notice the code changes the separator in the data by exchanging the comma as originally written to a space, colon, and another space. The code does this by splitting the line (string) read into parts by comma. The columns data contains three parts. We use the join() method to rejoin the string and print it. Take a moment to read through the code, and you will see these aspects. As you can see, Python is easy to read.

Now that we’ve experimented briefly with Python on our PC (we will see more of this in the next chapter), let’s see how to use MicroPython on our Raspberry Pi Pico. We saw some of this as a demo, but this time you get to try it yourself.

How It Works

Recall that MicroPython is designed to work on small microcontroller platforms. Some of these microcontroller platforms use a special chip that contains the MicroPython binaries (libraries, basic disk I/O, bootstrapping, etc.) as well as the microcontroller, memory, and supporting components.

When you use a MicroPython board – like most microcontrollers – you must first write your code before executing it. If you use the REPL, you’re actually executing the code as you write it, and the code is not saved on the board. If you want to store your code and execute it on boot (for example), you must load it onto the board. You can do this in one of two ways. You can use a command-line utility designed to use raw REPL, which allows Python code to be entered and executed on the board from a script to effect file operations, or you can use Thonny to write and copy your program (script file) to the board. Let’s see how to use each of these.

Note

Some other MicroPython boards have a USB flash drive that mounts when you connect it to your computer using a USB cable. The Pico does not have this feature, so you must use a utility or Thonny to edit or copy files on the Pico.

File Operations with a Utility

There are several utilities available for working with files on the Pico. All use some form of the raw REPL to execute filesystem operations via Python code to list and copy files. We will see how to use one of the following utilities, but the other options work in a similar fashion:
Let’s see how to use the Adafruit MicroPython tool (ampy). You can install ampy using the following command:
$ pip3 install adafruit-ampy
Once installed, you can use ampy as a command-line tool to execute file operations. Listing 2-4 shows the help feature for ampy.
ampy --help
Usage: ampy [OPTIONS] COMMAND [ARGS]...
  ampy - Adafruit MicroPython Tool
  Ampy is a tool to control MicroPython boards over a serial connection.
 Using ampy you can manipulate files on the board's internal filesystem and
 even run scripts.
Options:
  -p, --port PORT    Name of serial port for connected board.  Can optionally
                     specify with AMPY_PORT environment variable.  [required]
  -b, --baud BAUD    Baud rate for the serial connection (default 115200).
                     Can optionally specify with AMPY_BAUD environment
 variable.
  -d, --delay DELAY  Delay in seconds before entering RAW MODE (default 0).
                     Can optionally specify with AMPY_DELAY environment
 variable.
  --version          Show the version and exit.
  --help             Show this message and exit.
Commands:
  get    Retrieve a file from the board.
  ls     List contents of a directory on the board.
  mkdir  Create a directory on the board.
  put    Put a file or folder and its contents on the board.
  reset  Perform soft reset/reboot of the board.
  rm     Remove a file from the board.
  rmdir  Forcefully remove a folder and all its children from the board.
  run    Run a script and print its output.
Listing 2-4

Adafruit MicroPython Tool (ampy) Help

Here, we see how to use options to connect to our Pico as well as the commands available. We only need to specify the port and optionally the baud rate and then one of the eight commands. For example, if you want to connect to the board on Windows 10 (COM3) with a baud rate of 115200 and list the contents of the filesystem, we use the following command:
$ ampy -p COM3 -b 115200 ls

If you are using Linux or macOS, you would use the device file such as /dev/tty… in place of COM3.

Note

Adafruit has discontinued the development of ampy to concentrate on their CircuitPython variant, but the utility is the best of the available utilities and easiest to use.

Let’s see ampy in action. Begin by creating a file on your PC with the following contents. Save it as hello_pico.py.
print("Hello from Pico!")
Now, open a terminal on your PC and navigate to the folder where you saved the file. Then, enter the following command to connect to the Pico:
$ ampy -p COM3 -b 115200 put hello_pico.py
You won’t see any output to know if the file copy worked, but you can list the files in the filesystem with the following command:
$ ampy -p COM3 -b 115200 ls
/hello_pico.py
Here, we see the file was copied. We can run (execute) the file with the following command:
$ ampy -p COM3 -b 115200 run hello_pico.py
Hello from Pico!
Finally, you can remove the file to save some space on the filesystem for other files. Note that the Pico has only 1.4MB of space to save files.
$ ampy -p COM3 -b 115200 rm hello_pico.py

As you can see, it is easy to use ampy, but it is not as nice as a GUI. That’s where Thonny makes these operations nicer.

File Operations with Thonny

You can perform filesystem operations on your Pico from inside Thonny. You should first connect your Pico board to your PC. Then, simply click the ViewFiles menu. You will then see a tool window open that allows you to see the files on both your PC from the current working directory and those on your Pico.

You can right-click any files listed to download them from your Pico to your PC, or you can use the submenu to see all of the available commands as shown in Figure 2-7.
Figure 2-7

File viewer (Thonny)

To copy files to the Pico using Thonny, first navigate to the file from your PC in the top part of the file tool window and then select the file as shown in Figure 2-8. Recall, we created the hello_pico.py file in the last section.
Figure 2-8

Copy a file to the Pico – select a file (Thonny)

Next, right-click the file and select Upload to / as shown in Figure 2-9.
Figure 2-9

Copy a file to the Pico – copy (Thonny)

Now you will see the file on the Pico. You can then open the file by double-clicking it in the Pico section. A new tab will open with square brackets around the name to indicate the file is a remote file. Now you can run it with the run command as shown in Figure 2-10.
Figure 2-10

Open and execute a file on the Pico (Thonny)

As you can see, it is very easy to use Thonny to work with the files on the Pico.

Now it’s time to take a tour of what we can do with MicroPython. The following section uses several example projects to show you what you can do with a MicroPython board. Once more, I introduce the examples with a minimal amount of explanation and details about the hardware. We will learn much more about the hardware in Chapter 4.

Off and Running with MicroPython

If you’re like me when encountering new technologies, you most likely want to get started as soon as you can. If you already have a Pico, you can follow along with the examples in this section and see a few more examples of what you can do with MicroPython. The examples will use the onboard LED, which can be found to the left of the micro-USB port as shown in Figure 2-11.
Figure 2-11

Locating the onboard LED (Pico)

The LED is a single-color (green) LED that you can turn on and off. That might not seem very interesting, but using this simple component will help you get used to creating new code files in Thonny, uploading them to your Pico, and executing them.

Tip

If you’re wondering what protocols are supported on the pins, you can visit https://datasheets.raspberrypi.com/pico/Pico-R3-A4-Pinout.pdf to see a complete list of the pins and their uses.

You will also learn more about how to interface with the hardware, but don’t worry too much about what each line of code does. We’ll learn more as we progress to more complex examples.

Example 1 – Blink the LED

In this example, we will write code to turn on the LED on the board. Rather than simply turning it on, let’s use a construct called a loop to turn it on and off every 250 milliseconds. Thus, it will flash rather quickly. Before I explain the code, let’s look at the completed code. Listing 2-5 shows how the code would look. Don’t worry, I’ll explain each of the lines of code after the listing.
#
# Beginning MicroPython – Chapter 2
#
# Example 1 - Blink the LED
#
# Dr. Charles Bell
#
import time
 from machine import Pin # Import the Pin class from the machine library
led = Pin(25, Pin.OUT)  # Get the LED instance (from GPIO pin 25)
led.off()               # Make sure it's off first
for i in range(0, 20):  # Run the indented code 20 times
    led.on()            # Turn LED on
    time.sleep(0.250)   # Wait for 250 milliseconds
    led.off()           # Turn LED off
    time.sleep(0.250)   # Wait for 250 milliseconds
led.off()               # Turn the LED off at the end
print("Done!")          # Goodbye!
Listing 2-5

Blink the LED

The first lines of code are comment lines. These are ignored by MicroPython and are a way to communicate to others what your program is doing. If you are using the REPL console instead of following along with this tutorial, feel free to skip the comment lines when entering the code.

Next is a line of code that is used to import the base hardware library (machine). This library is specific to the Pico and makes available all the components on the board. We also import the time library as we will need to use the sleep() method later to pause execution. This will allow the LED to remain on (or off) for a specific amount of time.

The next two lines of code initialize a variable (led) by using the Pin class from the machine library (Pin) to instantiate a variable of the Pin class representing the onboard LED found on GPIO number 25 (the physical number of the pin). This creates an instance of that object that we can use. In this case, we immediately turn the LED off by calling led.off().

Next is the main portion of the code – a loop! In this case, it is a for loop designed to run the block of code below it as indicated by the indentation 20 times. The for loop uses a counter, i, and the values 1 through 20 as returned by the range(1, 20) function. Within the body of the loop (the indented portion), we first turn the LED on with led.on(), wait 250 milliseconds using the time.sleep () method, then turn the LED off again and wait another 250 milliseconds. We use 0.250 because the sleep() method uses seconds rather than milliseconds. Finally, we turn the LED off and print a message that we’re done.

You can enter this code line by line into the REPL console if you’d like, but since we have such a nice IDE with Thonny, let’s use that. Start by opening a new file using the FileNew menu and type the lines of code as shown in the listing. Next, let’s save the file with the FileSave menu. This will open a new dialog as shown in Figure 2-12 where you can choose where to save the file. You should choose the Raspberry Pi Pico option.
Figure 2-12

Where to save to? dialog (Thonny)

Next, you will be shown the save dialog where you can name the file as shown in Figure 2-13. If you have created directories on your Pico, you can navigate to where you’d like to save the file. Name the file example1.py and click OK.
Figure 2-13

Save dialog (Thonny)

Next, we can run the example. To do so, you can either click the Run button (small green button with an arrowhead on the toolbar) or click the RunRun current script menu. You will see the MicroPython console show in the shell tab as the program executes. You should also see the green LED on the Pico blink rapidly. Figure 2-14 shows an example of the code running in Thonny. If you want it to blink slower, just adjust the time.sleep() calls and increase the value to 0.500 or even 1.0.
Figure 2-14

Running example 1 (Thonny)

If you have been following along with this chapter, you should now see two files on your Pico as shown earlier.

Example 2 – Toggle the LED

Now, let’s modify our last example to use a helper function. In this case, we will use the toggle() method to turn the LEDs on and off. Basically, whatever state it is in, the toggle() sets it to the opposite. Let’s shake things up a bit and use a different loop (a while loop) with a counter inside the loop, and we’ll place out delay and toggle into a method we will create. So, it is like the previous example but, as you will see, demonstrates a bit more complexity. Since it is more complex, I will walk through the code in sections before presenting the completed code.

Recall from the last example, we must import two things: the Pin class from the machine library and the time library as shown in the following:
import time
from machine import Pin
Next, we are going to use a new concept called constants. There are simply placeholders for values we will use that never change. They are especially helpful when used in more than one place in the code. We will create one for the time to sleep and another for the maximum number of blinks, which we will use to end the while loop. The following shows the correct syntax for the constants:
SLEEP_TIME = 0.250           # Time to sleep in milliseconds
MAX_BLINKS = 20              # Max number of blinks
Next, we create the new method named blink_led() as shown in the following. Here, we define the method with the def clause and indent all of the code we want to include. Here, we call the toggle() method and time.sleep(). This is a common way to organize your code and make it possible to reuse some lines of code from different places in your code to eliminate duplication:
def blink_led():
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
Following that, we instantiate a class variable for the pin like we did before, and then we initialize a counting variable for use in the loop. The while loop is written differently than the for loop. In this case, we place a condition at the top of the loop, and the loop is executed so long as the condition is true. To make it false and stop the loop, we simply increment the counter as part of the body of the loop as follows:
count = 0                    # Initialize the counter
while count < MAX_BLINKS:    # Run while counter < max num blinks
    blink_led()              # Toggle the LED
    count = count + 1        # Increment the counter
The rest of the code is the same as the last example. Listing 2-6 shows the completed code. Read through it a few times until you’re convinced it will work.
#
# Beginning MicroPython – Chapter 2
#
# Example 2 - Toggle the LED
#
# Dr. Charles Bell
#
import time
from machine import Pin
# Constants
SLEEP_TIME = 0.250           # Time to sleep in milliseconds
MAX_BLINKS = 20              # Max number of blinks
# Create a method to toggle the LED and wait 250 milliseconds
def blink_led():
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
led = Pin(25, Pin.OUT)       # Get the LED instance (from GPIO pin 25)
led.off()                    # Make sure it's off first
count = 0                    # Initialize the counter
while count < MAX_BLINKS:    # Run while counter < max num blinks
    blink_led()              # Toggle the LED
    count = count + 1        # Increment the counter
led.off()                    # Turn the LED off at the end
print("Done!")               # Goodbye!
Listing 2-6

Example 2. Toggle the LED

If you’re following along, go ahead and save this file on your Pico as example2.py. See the previous example for instructions on how to save the file.

When you run the code by clicking the Run button (small green button with an arrowhead on the toolbar) or clicking the RunRun current script menu, you will see the LED turn on and off.

However, there is a bug (defect or logic error) in this code. Can you spot it? I’ll give you a hint. Run the code and count how many times the LED turns on.

How many did it turn on? Now, go back and run the first example again. How many times did the LED turn on there? If you discovered the LED turns on 10 times for this example, but 20 for the last example, you’ve found the artifact (data) that shows the logic error. Now, where is the logic error?

If you’re thinking it has something to do with either the blink_led() method or the constant, you’re on the right track.

Now, look at our first example. What did we do inside the for loop? We turned it on, waited, then turned it off, and waited some more. That effected a “blink” of the LED, and we did it 20 times.

But in this example, we use toggle(), which only turns the LED on if off and off if on. We did this 20 times too. Do you see where we went wrong?

You may be tempted to fix the issue by changing the constant MAX_BLINKS to 40 and that would work, but the logic error is actually in the blink_led() method. We should have called the toggle() method twice as shown in the following:
def blink_led():
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)

Go ahead and make that change. You should now see the LED illuminate 20 times.

It is this sort of error that we can introduce unknowingly especially if we build our own logic to control hardware.3 That’s why it is always best to let the hardware do the work for us, which we are going to do in the next example.

Example 3 – Timer

This example demonstrates how to use a timer with a callback function, which is simply a method we create to execute when the timer “triggers.” That is, we create a function in our code and then tell MicroPython to execute that function when the timer alarm or frequency cycles (also called trigger). This example is based on the previous example, but with a timer instead of a loop.

We will use the same imports as the last example except with one additional library – the Timer library as shown in the following:
import time
from machine import Pin, Timer
We still need the SLEEP_TIME constant, but not the MAX_BLINKS constant. The blink_led() is altered slightly, however. We add the timer variable in the parameter list as shown in the following. This is so that we can use the method as a callback for the Timer class:
def blink_led(timer):
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
Next, we set up the pin as before and initiate a Timer class instance variable as follows:
led = Pin(25, Pin.OUT)       # Get the LED instance (from GPIO pin 25)
timer = Timer()              # Get the timer instance
led.off()                    # Make sure it's off first
Now we can set up the timer using a frequency of 2.0, which means fire (call) the blink_led() method twice per second (or every 500 milliseconds) with a mode of periodic, and we pass in the address of the blink_led() method by not specifying the () as follows:
timer.init(freq=2.0, mode=Timer.PERIODIC, callback=blink_led)
time.sleep(10)               # Wait for 10 seconds
timer.deinit()               # Turn off the timer

Notice we add a sleep() method to sleep for 10 seconds and then call deinit() for the timer. This will effectively let the code run for 10 seconds blinking the LED twice per second for 20 iterations. We call the deinit() to turn off the timer. Otherwise, the timer will continue to run even when our code has completed. So, yes, you can spawn code to execute by itself. Cool, eh?

Listing 2-7 shows the completed code. Read through it a few times until you’re convinced it will work.
#
# Beginning MicroPython – Chapter 2
#
# Example 3 - Blink the LED with a Timer
#
# Dr. Charles Bell
#
import time
from machine import Pin, Timer
# Constants
SLEEP_TIME = 0.250           # Time to sleep in milliseconds
# Create a timer callback method to toggle the LED
def blink_led(timer):
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
    led.toggle()             # Toggle the LED
    time.sleep(SLEEP_TIME)
led = Pin(25, Pin.OUT)       # Get the LED instance (from GPIO pin 25)
timer = Timer()              # Get the timer instance
led.off()                    # Make sure it's off first
# Use a timer to control the blink twice per second or
# every 500 milliseconds
timer.init(freq=2.0, mode=Timer.PERIODIC, callback=blink_led)
time.sleep(10)               # Wait for 10 seconds
timer.deinit()               # Turn off the timer
led.off()
print("Done!")               # Goodbye!
Listing 2-7

Example 3. Blink the LED with a Timer

If you’re following along, go ahead and save this file on your Pico as example3.py. See the previous example for instructions on how to save the file.

When you run the code by clicking the Run button (small green button with an arrowhead on the toolbar) or clicking the RunRun current script menu, you will see the LED turn on and off. Try to count the number of times the LED is turned on to convince yourself this code works as described.

Here, we see a more complex example of blinking the LED without using a counting loop. While the timer may seem strange, it is much easier and less error-prone than the loop option of the previous examples.

Saving Your Work

If you have followed along thus far, you should have five MicroPython files on your Pico (hello_pico.py, file_io.py, example1.py, example2.py, and example3.py). Unless you created these on your PC first, you only have copies on your Pico. You can download these to your PC from your Pico using Thonny by right-clicking the file in the Pico section and then choosing Download to <current_directory> as shown in Figure 2-15. Repeat until all files have been downloaded to your PC.
Figure 2-15

Downloading files from the Pico to your PC (Thonny)

Summary

MicroPython is a very exciting addition to the microcontroller world. For the first time, beginners do not need to learn a new operating system or a complex programming language like C or C++ to program the microcontroller. MicroPython permits people with some or even no programming experience to experiment with electronics and build interesting projects. Thus, MicroPython provides opportunities for more hobbyists and enthusiasts who just want to get their projects working without a steep learning curve.

In this chapter, we discovered the major features of MicroPython. We also discovered that MicroPython is based on the Python that we find on our PCs. Best of all, we saw firsthand how MicroPython works on the Pico.

In the next chapter, we will dive into a programming tutorial on using Python and MicroPython. The chapter is very much a lightning tour and intended to help guide you to the point where you can write (and understand) the examples in this book.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
44.200.27.215