Feather programming

Programming your Feather RP2040 microcontroller #


Set-Up Procedure #

Alternative Feather programming tutorials #

Adafruit’s CircuitPython Tutorials are great if you’re new to this stuff. Please take the time to run through them; it’s an investment worth making. Microcontrollers are not going away soon.

When stuff goes wrong #

The most common problem with microcontrollers is difficulty communicating between the computer and the microcontroller. You might see messages like “Circuit Python device not connected.”

In this case, you should hold down the BOOTSEL button while pressing and releasing the RESET button, to make sure your computer sees the Feather’s CIRCUITPY drive.

You can also try unplugging the Feather and plugging it in again and restarting the Mu Editor.

So, how do I make this “code” you mention? #

Start by exploring the CircuitPython tutorial provided by Adafruit, starting at the page Exploring Your First CircuitPython Progarm and working through the next several pages.

Learn the basics of Python syntax at the easy-to-follow Python W3 Schools website.

Then review and bookmark the CircuitPython Essentials page from Adafruit.


Using Mu to run code on your Feather #

Save your Python code as the file code.py on your Feather, and it will start running immediately.

To interrupt your Feather and stop the code, open the Mu Serial monitor, click within the Serial monitor, and use CTRL-C.

To return the Feather to running the code, use CTRL-D in the serial monitor.

Things to know about Python syntax #

  • In Python, a line break (new line) indicates a new command. You might have seen other programming languages use semicolons or parentheses.
  • In Python, indentation (space at the beginning of a line) is very important! To indicate nested or sub-section blocks of code (e.g., of a loop or function), you must use indentation from the left edge of the screen. Python uses whitespace (indentation amount) to determine “scope” — that is, to figure out what blocks of code define other code, or belong within a higher level of code.
  • Use the # symbol to indicate the start of a comment (indicate that certain text is documentation of your code, rather than a command).
# Python interprets this line as a comment.
print(“Hello ME 30!”)

Python variables #

Create a variable by assigning a value to it. Python will automatically determine what type of variable it is (e.g., an integer, a decimal, a string) based on its initial assignment.

x = 30
y = 30.0
address = “200 Boston Ave.”

Python has no command for simply declaring the existence of a variable.

How to see text output by a Python program #

You’ll need to open the serial monitor in the Mu editor.


A few exciting commands in some CircuitPython-specific libraries #

Here are some Python commands that you might want to start with. To use all but the print() command, you need to start your Python code by importing the libraries specified below (TIME, BOARD, DIGITALIO, PWMIO, ANALOGIO).

print(): Prints the value of whatever variable is listed inside the ().

print(“[string]”): Prints exactly the text included inside the (“ “)

To see the text generated by print(), be sure the serial monitor in your Mu Editor is open.

print(([variable],)): With the extra parentheses and comma, creates a “tuple” (a pair of values) that the Mu editor will show on its x-y plotter

To see the points generated by print(([var],)), be sure the plotter in Mu is open.

TIME library #

To use this command, include the command “import time” at the start of your code.

time.sleep(N): do nothing for N seconds

BOARD and DIGITALIO library #

To use these commands, include the command “import board” and “import digitalio” at the start of your code.

dir(board): spits out the names of the all the pins available on your Feather

xyz = digitalio.DigitalInOut(board.[pin name or number]): calls up the digitalio library and creates a new object called xyz that will hold information about a specific pin on a microcontroller board. The pin names and numbers are on the board’s pinout diagram, e.g, D6, D5, LED, etc.

xyz.direction = digitalio.Direction.OUTPUT: tells the Feather to treat the pin for object xyz as a voltage output, not an input

xyz.direction = digitalio.Direction.INPUT: tells the Feather to treat the pin for object xyz as a voltage input

xyz.value: the voltage value at the pin for object xyz

xyz.value = 1: sets the voltage at the pin for xyz to be “high.” For the Feather, that’s 3.3 V

xyz.value = True: another way to set the voltage high

xyz.value = 0 sets the voltage for the digital variable xyz to be “low,” i.e., ground or 0 V

xyz.value = False: another way to set the voltage low

PWMIO library #

To use these commands, include the command “import pwmio” at the start of your code.

xyz = pwmio.PWMOut(board.[pin name or number], frequency =[initial PWM frequency], duty_cycle=[initial PWM duty cycle])

creates a new object called “xyz” that will hold all the information about sending out pulse-width modulation at a particular pin

xyz.duty_cycle = 32000

at whatever Feather pin belongs to the PWM object xyz, changes the duty cycle of the PWM voltage to 32000. For the RP2040 chip on the Feather, the duty cycle maximum is 65535; max duty cycle means the output is high 100% of the time.

ANALOGIO library #

xyz = analogio.AnalogIn(board.A1): creates an object called xyz and connects xyz to A1 as an analog input.

The code below will plot the value of the voltage coming in at analog input pin A1.

import time
import analogio
import board

inputvoltage = analogio.AnalogIn(board.A1)

while True:
    print((inputvoltage.value,))
    time.sleep(0.1)

Libraries for sensors and stepper motors #

If you want to program more specialized devices like stepper motors or particular sensors, you may need to download additional CircuitPython libraries (that don’t come with CircuitPython uf2 file itself) onto your Feather. You can learn about how that works at the Welcome to CircuitPython libraries page

The full set of CircuitPython libraries for the Feather can be downloaded here.

NOTE: I recommend downloading the entire bundle to your laptop, and then transferring ONLY the libraries you need for your game to your Feather. Transferring the entire bundle to your Feather will take quite a long time.

For distance sensor reading, check out this page to see what libraries you need.

For stepper motor control, you’ll need the adafruit_motor library (and two H-bridges). You can find helpful wiring diagrams here.

State Machine Code #

Often when using a microcontroller within a electromechanical system, you need to be able to check for the state of inputs while also running motors, lights, and other actuators. Writing code for “state machines” is a useful technique for this situation. At this link is one way to set up state machines in CircuitPython. This code flashes an LED, constantly checks for a button press, and flashes a different LED when the button is pressed.

CircuitPython Reference Pages #

If you want to check the details of these functions or see what else is available, the canonical reference is the CircuitPython Essentials page.