Adafruit Gemma m0 2
Adafruit Gemma m0 2
Guide Contents 2
Overview 5
Guided Tour 8
Pinouts 10
JST Battery Input 10
Power Pads 10
Input/Output Pads 11
Common to all pads 11
Unique pad capabilities 11
Secret SWD and Reset Pads 11
Windows Driver Installation 13
Manual Driver Installation 14
CircuitPython 15
Reinstalling and Updating CircuitPython 15
Flashing 16
Flashing UF2 16
Flashing with BOSSAC 18
After flashing 18
CircuitPython Blinky 19
code.py 19
Status LED 20
Debugging 20
Libraries 20
More info 20
Serial Console (REPL) 21
Windows 21
Serial Drivers (for Windows 7) 21
Determine Your Serial Port 21
Install Serial Port Terminal Software 22
Mac OSX and Linux 23
Using the REPL 25
Installing Libraries 27
Installing the bundle 27
The Gemma M0 is a super small microcontroller board, with just enough to build many simple projects. It may look
small and cute: round, about the size of a quarter, with friendly alligator-clip sew pads. But do not be fooled! The
Gemma M0 is incredibly powerful! We've taken the same form factor we used for the original ATtiny85-based
Gemma (http://adafru.it/duB) and gave it a power up. The Gemma M0 has swapped out the lightweight ATtiny85 for
a ATSAMD21E18 powerhouse.
It will super-charge your wearables! It's just as small, and it's easier to use, so you can do more.
The most exciting part of the Gemma M0 is that while you can use it with the Arduino IDE, we are shipping it with
CircuitPython on board. When you plug it in, it will show up as a very small disk drive with main.py on it. Edit
main.py with your favorite text editor to build your project using Python, the most popular programming language.
No installs, IDE or compiler needed, so you can use it on any computer, even ChromeBooks or computers you can't
install software on. When you're done, unplug the Gemma M0 and your code will go with you.
So what are you waiting for? Pick up a Gemma M0 today and be amazed at how easy and fast it is to get started
with Gemma and CircuitPython!
Let me take you on a tour of your Gemma M0! Each Gemma M0 is assembled here at Adafruit and comes chock-
full of good design to make it a joy to use.
Micro B USB connector - We went with the tried and true micro-B USB connector for power and/or USB
communication (bootloader, serial, HID, etc). Use with any computer with a standard data/sync cable.
RGB DotStar LED - Instead of an always-on green LED we provide a full RGB LED. You can set it to any
color in the rainbow. It will also help you know when the bootloader is running (it will turn green) or if it failed to
initialize USB when connected to a computer (it will turn green). By default after you boot up the Gemma M0 it
will turn a lovely violet color.
Red #13 LED - this LED does double duty. Its connected with a series resistor to the digital #13 GPIO pin. It
pulses nicely when the Gemma is in bootloader mode, and its also handy for when you want an indicator LED.
JST Battery Input - take your Gemma anywhere and power it from an external battery. This pin can take up
6V DC input, and has reverse-polarity, over-curent and thermal protections. The circuitry inside will use either
the battery or USB power, safely switching from one to the other. If both are connected, it will use whichever
has the higher voltage. Works great with a Lithium Polymer battery or our 3xAAA battery packs with a JST
connector on the end. There is no built in battery charging (so that you can use Alkaline or Lithium batteries
safely)
Vout (Voltage Output) - This pin will give you either the battery power or USB power, whichever has a higher
voltage. Its great when you want to power something like NeoPixels, that might use more than the 500mA
available from the onboard regulator
3V Regulator - The on-board voltage regulator can supply up to 500mA at a steady 3.3V from up to 6VDC
Sewing and Alligator clip friendly pads - You can easily sew to these pads, and they're gold plated so they
wont corrode (oxidize). You can also use alligator clips or solder directly to them.
3 General Purpose I/O (GPIO) Pads! - 3 GPIO pins, at 3V logic, check the next section for a detailed pinout
You can plug anything from around 4 VDC up to 6 VDC. That means any single-cell LiPoly, or 3-4 AAA or AA
batteries. This input is polarity protected. Gemma and DotStar LED light up, you're good to go. You can turn off the
battery with the on/off switch, which will completely disconnect power on the Gemma M0.
Power Pads
Half of the pads on the Gemma M0 are related to power in and out:3Vo , Vout and GND
Vout - This is a voltage OUTPUT pin, it will be connected to either the USB power or the battery input,
whichever has the higher voltage. This output does not connect to the regulator so you can draw as much
current as your USB port / Battery can provide (in general, thats about 500mA)
3Vo - This is the 3.3V OUTPUT pad from the voltage regulator. It can provide up to 500mA at a steady 3.3V.
Good for sensors or small LEDs or other 3V devices.
GND is the common ground pin, used for logic and power. It is connected to the USB ground and the power
regulator, etc. This is the pin you'll want to use for any and all ground connections
Each pad can provide up to ~20mA of current. Don't connect a motor or other high-power component directly to the
pins! Instead, use a transistor to power the DC motor on/off (http://adafru.it/aUD)
On a Gemma M0, the GPIO are 3.3V output level, and should not be used with 5V inputs. In general, most 5V
devices are OK with 3.3V output though.
The three pads are completely 'free' pins, they are not used by the USB connection, LEDs, DotStar, etc so you
never have to worry about the USB interface interfering with them when programming
SWDIO
SWCLK
Reset
On the off chance you want to reprogram your Gemma M0 or debug it using a Cortex M0 debug/programmer, you
will need to solder/connect to these pads. We use them for testing and you will likely never need it but they are
there if you do!
Before you plug in your board, you'll need to possibly install a driver!
Run the installer! Since we bundle the SiLabs and FTDI drivers as well, you'll need to click through the license
Select which drivers you want to install, we suggest selecting all of them so you don't have to do this again!
You can also, optionally, install the Arduino Gemma (different than the Adafruit Gemma!), Huzzah and Metro
drivers
And point windows to the Drivers folder when it asks for the driver location
Your Gemma M0 already comes with CircuitPython but maybe there's a new version, or you overwrote your
Gemma M0 with Arduino code! In that case, see the below for how to reinstall or update CircuitPython. Otherwise
you can skip this and go straight to the next page
Files ending in .uf2 can be flashed onto a virtual drive when in bootloader mode. Files that end with.bin can be
flashed with esptool.py or bossac.
You will see a list of all available flavors of CircuitPython. Since we support a lot of different hardware, we have a
long list of available downloads!
Regardless of what method you use, you must first get the board into the bootloader mode. This is done by double
clicking the reset button. The board is in bootloader mode when the red led fades in and out. Boards with the status
neopixel will also show USB status while the red led fades. Green means USB worked while red means the board
couldn't talk to the computer. The first step to troubleshooting a red neopixel is trying a different USB cable to make
sure its not a charge-only cable.
Flashing UF2
The Gemma M0 comes with a new bootloader called UF2 that makes flashing CircuitPython even easier than
before. This beta bootloader allows you to drag so-called ".uf2" type files onto the BOOT drive. For more
information, check out our UF2 bootloader page. (http://adafru.it/vQd)
Start by ejecting or "safely remove" the CIRCUITPY drive if its present, then double-clicking the reset button while it
is plugged into your computer. You should see a new disk drive 'pop up' called GEMMABOOT or similar, and the
DotStar on your board glow green.
The drive will contain a few files. If you want to make a 'backup' of the current firmware on the device, drag-off and
save the CURRENT.UF2 file. Other that that you can ignore the index.htm and info_uf2.txt files. They cannot be
deleted and are only for informational purposes.
Next up, find the Gemma M0 UF2 file in the github downloads list:
Click to download and save the file onto your Desktop or somewhere else you can find it
Once the full file has been received, the board will automatically restart into CircuitPython. Your computer may warn
about ejecting the drive early, if it does, simply ignore it because the board made sure the file was received ok.
To flash with bossac (BOSSA's command line tool) first download the latest version fromhere. The mingw32 version is
for Windows, apple-darwin for Mac OSX and various linux options for Linux. Once downloaded, extract the files from
the zip and open the command line to the directory with bossac.
bossac -e -w -v -R ~/Downloads/adafruit-circuitpython-gemma_m0-1.0.0.bin
This will erase the chip, write the given file, v erify the write and Reset the board. After reset, CircuitPython should be
running. Newer boards with the UF2 bootloader may cause a warning of an early eject of a USB drive but just ignore
it. Nothing important was being written to the drive.
After flashing
After a successful flash by bossac or UF2 you should see a CIRCUITPY drive appear.
code.py
After plugging in a board with CircuitPython into your computer a CIRCUITPY drive will appear. At first, the drive
may be empty but you can create and edit files on it just like you would on a USB drive. On here, you can save a
code.py (code.txt and main.py also work) file to run every time the board resets. This is the CircuitPython equivalent
of an Arduino sketch. However, all of the compiling is done on the board itself. All you need to do is edit the file.
So, fire up your favorite text editor, such as Notepad on Windows, TextEdit on Mac ordownload Atom (my favorite),
and create a new file. In the file copy this:
import digitalio
import board
import time
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = not led.value
time.sleep(0.5)
Now, save the file to the drive ascode.txt (code.py also works). After a brief time, the board's red LED should begin to
flash every second.
Do not click the RESET button after saving your code file! It could cause the computer to not-finish writing your
code to disk. Just wait a few seconds and it should automatically restart the python code for you!
Debugging
Did the status LED flash a bunch of colors at you? You may have an error in your code. Don't worry it happens to
everyone. Python code is checked when you run it rather than before like Arduino does when it compiles. To see
the CircuitPython error you'll need to connect to the serial output (like Arduino's serial monitor).
If you are new to Python try googling the error first, if that doesn't find an answer feel free to drop by thesupport
forum.
Libraries
Using libraries with CircuitPython is also super easy. Simply drag and drop libraries onto the CIRCUITPY drive or
into a lib folder on the drive to keep it tidy.
Find CircuitPython libraries on GitHub using the topic and through our tutorials.
Make sure the libraries are for CircuitPython and not MicroPython. There are some differences that may cause it to
not work as expected.
More info
Guides and Tutorials
API Reference
Adafruit forum
Libraries
Also, because CircuitPython is a variant of Python, it too has a read-evaluate-print-loop or 'REPL' for short. The
REPL lets you run individual commands and load up code interactively and is therefore great for testing a new idea.
However, the code typed into the REPL isn't saved anywhere so make sure and save it elsewhere (like code.py for
example.)
Windows
Serial Drivers (for Windows 7)
If you are using Windows 7 you will need to install drivers. Click below to download the driver package and install it!
This is not necessary for Mac, Linux or Windows 10+.
First open a terminal program. On Mac OSX, Terminal comes installed andiTerm2 (http://adafru.it/xZd) can be
downloaded. On Linux there are a variety available such as gnome-terminal (called Terminal) and Konsole on KDE.
Now before plugging in the board, typels /dev/tty.* to view existing serial connections.
Next, plug in the board. There should be one new serial connection that is for your board. Typically on Mac OSX its
something like /dev/tty.usbmodem* and on Linux its /dev/ttyACM*.
When you're done using screen most versions of it allow you to exit by pressingCtrl-a then k then y or pressing
Ctrl-a then typing :quit and pressing enter.
If you can't get a >>> prompt to appear try pressing Ctrl-c a couple times to interrupt any running program on the
board.
You might get a Traceback and KeyboardInterrupt that lets you know the current Python program has stopped,
and you'll get a prompt:
Your board ships with a lib folder already, its in the base directory of the drive:
CircuitPython libraries work in the same was as regular Python modules so thePython docs are a great reference
for how it all should work. In Python terms, we can place our library files in the lib directory because its part of the
Python path by default.
One downside of this approach of separate libraries is that they are not built in. To use them, one needs to copy
them to the CIRCUITPY drive before they can be used. Fortunately, we provide a bundle full of our libraries.
Our bundle and releases also feature optimized versions of the libraries with the.mpy file extension. These files take
less space on the drive and have a smaller memory footprint as they are loaded.
We need to be selective about what libraries we load on the board because we can't simply fit them all like we can
on an Express board. So, lets take a look at this silly example below which uses a SI7021 I2C temperature sensor.
import adafruit_si7021
import busio
After saving that as code.py on the drive we see the status NeoPixel flashes that an error has occurred. Opening up
the serial console we see that an ImportError has occurred.
It says that no module exists named adafruit_si7021. Thats the library we need to download! Since we bought the
sensor from Adafruit its likely there is a library for in the official Adafruit bundle. If its not an Adafruit part or its
missing, we can also check the Community bundle which has libraries contributed by the community.
Visiting the bundle release page will show us information on the latest release including a list of all the versions of
the included drivers. Scrolling to the bottom of the page will reveal the downloads. We'll download the first zip file
which starts with adafruit-circuitpython-bundle.
Out of space!
The file system on the board is very tiny. (Smaller than an ancient floppy disk.) So, its likely you'll run out of space
but don't panic! There are a couple ways to free up space.
The board ships with the Windows 7 serial driver too! Feel free to delete that if you don't need it or have already
installed it. Its ~12KiB or so.
The simplest way of freeing up space is to delete files from the drive. Perhaps there are libraries in thelib that you
aren't using anymore or test code that isn't in use.
Use tabs
One unique feature of Python is that the indentation of code matters. Usually the recommendation is to indent code
with four spaces for every indent. In general, we recommend that too. However, one trick to storing more human-
readable code is to use a single tab character for indentation. This approach uses 1/4 of the space for indentation
and can be significant when we're counting bytes.
Luckily you can disable some of the extra hidden files that Mac OSX adds by running a few commands to disable
search indexing and create zero byte placeholders. Follow the steps below to maximize the amount of space
available on OSX:
First find the volume name for your board. With the board plugged in run this command in a terminal to list all the
volumes:
ls -l /Volumes
Look for a volume with a name like CIRCUITPY (the default for CircuitPython). The full path to the volume is
the /Volumes/CIRCUITPY path.
Now follow the steps from this question (http://adafru.it/u1c) to run these terminal commands that stop hidden files
from being created on the board:
Replace /Volumes/CIRCUITPY in the commands above with the full path to your board's volume if it's different. At
this point all the hidden files should be cleared from the board and some hidden files will be prevented from being
created.
However there are still some cases where hidden files will be created by Mac OSX. In particular if you copy a file
that was downloaded from the internet it will have special metadata that Mac OSX stores as a hidden file. Luckily
you can run a copy command from the terminal to copy files without this hidden metadata file. See the steps
below:
Once you've disabled and removed hidden files with the above commands on Mac OSX you need to be careful to
copy files to the board with a special command that prevents future hidden files from being created. Unfortunately
you cannot use drag and drop copy in Finder because it will still create these hidden extended attribute files in
some cases (for files downloaded from the internet, like Adafruit's modules).
To copy a file or folder use the -X option for the cp command in a terminal. For example to copy afoo.mpy file to
the board use a command like:
cp -X foo.mpy /Volumes/CIRCUITPY
Or to copy a folder and all of its child files/folders use a command like:
If you'd like to see the amount of space used on the drive and manually delete hidden files here's how to do so.
First list the amount of space used on the CIRCUITPY drive with the df command:
Oops! Another ImportError! Libraries can depend on other libraries so copying one file over may not be enough.
Looking in the bundle, there is an adafruit_bus_device directory. In Python terms this is a package. It contains module
files. Lets copy the folder over to make sure we get everything.
Lets check the serial connection again. Looks like it worked! We don't have any moreImportErrors and we can see the
temperature (in Celsius) and the relative humidity.
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
led = DigitalInOut(L)
led.direction = Direction.OUTPUT
analog0in = AnalogIn(A0)
analog1in = AnalogIn(A1)
analog2in = AnalogIn(A2)
def getVoltage(pin):
return (pin.value * 3.3) / 65536
while True:
print("A0: %f \t\t A1: %f \t\t A2: %f" %
(getVoltage(analog0in),
getVoltage(analog1in),
getVoltage(analog2in)))
time.sleep(0.1)
Creates three objects, one for each pad, and connects the objects to A0, A1 and A2 as analog inputs.
GetVoltage Helper
is our little helper program. By default, analog readings will range from 0 (minimum) to 65535
getVoltage(pin)
(maximum). This helper will convert the 0-65535 reading from pin.value and convert it a 0-3.3V voltage reading.
Main Loop
The main loop is simple, it will just print out the three voltages as floating point values (the %f indicates to print as
floating point) by calling getVoltage on each of our analog objects.
If you connect to the serial port REPL, you'll see the voltages printed out. By default the pins arefloating so the
voltages will vary. Try touching a wire from A0 to the GND or 3Vo pad to see the voltage change!
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
aout = AnalogOut(A0)
while True:
# Count up from 0 to 65535, with 64 increment
# which ends up corresponding to the DAC's 10-bit range
for i in range (0,65535,64):
aout.value = i
Creates an object aout that is connected to the only DAC pin available - A0.
Writing 65535 is the same as 1023 which is the top range and you'll get 3.3V output
Main Loop
The main loop is fairly simple, it just goes through the entire range of the DAC, from 0 to 65535, but increments 64
at a time so it ends up clicking up one bit for each of the 10-bits of range available.
CircuitPython is not terribly fast, so at the fastest update loop you'll get 4 Hz. The DAC isn't good for audio outputs
as-is.
Bigger boards like the Metro or Feather M0 have more code space and can perform audio playback capabilities via
the DAC.
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
import touchio
from board import *
import time
touch0 = touchio.TouchIn(A0)
touch1 = touchio.TouchIn(A1)
touch2 = touchio.TouchIn(A2)
while True:
if touch0.value:
print("A0 touched!")
if touch1.value:
print("A1 touched!")
if touch2.value:
print("A2 touched!")
time.sleep(0.01)
You can open up the serial console to see the touches detected and printed out.
touch0 = touchio.TouchIn(A0)
touch1 = touchio.TouchIn(A1)
touch2 = touchio.TouchIn(A2)
Main Loop
The main loop checks each sensor one after the other, to determine if it has been touched. Iftouch0.value returns
True, that means that that pad, A0, detected a touch. For each pad, if it has been touched, a message will print.
A small sleep delay is added at the end so the loop doesn't runtoo fast. You may want to change the delay from 0.1
seconds to 0 seconds to slow it down or speed it up.
Note that no extra hardware is required, you can touch the pads directly, but you may want to attach alligator clips
or foil tape to metallic or conductive objects. Try silverware, fruit or other food, liquid, aluminum foil, and items
around your desk!
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
import touchio
import busio
from board import *
import time
r=g=b=0
while True:
if touch0.value:
r = (r+1) % 256
if touch1.value:
g = (g+1) % 256
if touch2.value:
b = (b+1) % 256
setPixel(r, g, b)
Each of the three pads will change the color of the built in mini DotStar LED. You can touch each pad in order to
see the LED change colors, or you can open up the serial console to see the touches detected and the pixel color
printed out.
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
led = DigitalInOut(D13)
led.direction = Direction.OUTPUT
while True:
data = uart.read(32) # read up to 32 bytes
#print(data) # this is a bytearray type
if data != None:
led.value = True
led.value = False
In addition to the USB-serial connection you use for the REPL, there is also ahardware UART you can use. This is
handy to talk to UART devices like GPS's, some sensors, or other microcontrollers!
You can create a new UART object with uart = busio.UART(D0, D2, baudrate=9600) You can use only D0 and D2 as the
transmitting and receiving pins on the Gemma M0. Set the baudrate to whatever you like.
Once the object is created you read data in withread(numbytes) where you can specify the max number of bytes. It will
return a bytearray type object if anything was received already. Note it will always return immediately because there
is an internal buffer! So read as much data as you can 'digest'.
If there is no data available, read() will return None, so check for that before continuing.
The data that is returned is in a byte array, if you want to convert it to a string, you can use this handy line of code
which will run chr() on each byte:
To run this demo, you'll need something to generate UART data. We connected up a GPS!
Copy and paste the code block into main.py using your favorite text editor, and save the file, to run the demo
led = DigitalInOut(D13)
led.direction = Direction.OUTPUT
while True:
print("I2C addresses found:", [hex(i) for i in i2c.scan()])
time.sleep(2)
You can also use the Gemma to chat with I2C sensors and devices. Before you start, we recommend connecting it
up and doing an I2C scan so you can tell if it was detected.
You can create the I2C devices on the Gemma M0'sD2 (SCL) and D0 (SDA) pins.
Then run a scan with i2c.scan() It will return an array of addresses, but since usually they are referred to in hex
format, you may want to convert the array to hexadecimals with [hex(i) for i in i2c.scan()])
led = DigitalInOut(D13)
led.direction = Direction.OUTPUT
si7021 = adafruit_si7021.SI7021(i2c)
while True:
print("Temp: %0.2F *C Humidity: %0.1F %%" % (si7021.temperature, si7021.relative_humidity))
time.sleep(1)
Then check the REPL. If you have not yet used this chip you may get anImportError: no module named
'adafruit_si7021'
Check out our page on Installing Libraries to learn how to download the driver bundle and drag the driver you
need to the lib folder (http://adafru.it/yCK)
You will also need the adafruit_bus_device library folder - that will give you I2C access in a nice manner!
Once you're done you'll see you have the libraries installed:
Finally if you re-run you will be able to see the temperature and humidity data from the sensor:
gc.free_mem()
Random Numbers
import urandom
urandom.randint(min, max) will give you an integer number between min and max
After you have downloaded and installed the latest version of Arduino IDE, you will need to start the IDE and
navigate to the Preferences menu. You can access it from theFile menu in Windows or Linux, or the Arduino
menu on OS X.
To find the most up to date list of URLs you can add, you can visit the list ofthird party board URLs on the Arduino
IDE wiki (http://adafru.it/f7U). We will only need to add one URL to the IDE in this example, butyou can add
multiple URLS by separating them with commas. Copy and paste the link below into the Additional Boards
Manager URLs option in the Arduino IDE preferences.
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
Adafruit AVR Boards - Includes support for Flora, Gemma, Feather 32u4, Trinket, & Trinket Pro.
Adafruit SAMD Boards - Includes support for Feather M0, Metro M0, Circuit Playground Express, Gemma
M0 and Trinket M0
Arduino Leonardo & Micro MIDI-USB - This adds MIDI over USB support for the Flora, Feather 32u4, Micro
and Leonardo using the arcore project (http://adafru.it/eSI).
If you have multiple boards you want to support, say ESP8266 and Adafruit, have both URLs in the text box
separated by a comma (,)
Once done click OK to save the new preference settings. Next we will look at installing boards with the Board
Manager.
Now continue to the next step to actually install the board support package!
Now that you have added the appropriate URLs to the Arduino IDE preferences in the previous page, you can open
the Boards Manager by navigating to the Tools->Board menu.
Once the Board Manager opens, click on the category drop down menu on the top left hand side of the window and
select Contributed. You will then be able to select and install the boards supplied by the URLs added to the
prefrences.
You can type Arduino SAMD in the top search bar, then when you see the entry, clickInstall
You can type Adafruit SAMD in the top search bar, then when you see the entry, clickInstall
Even though in theory you don't need to - I recommend rebooting the IDE
Quit and reopen the Arduino IDE to ensure that all of the boards are properly installed. You should now be able to
select and upload to the new boards listed in the Tools->Board menu.
Feather M0 (for use with any Feather M0 other than the Express)
Feather M0 Express
Metro M0 Express
Circuit Playground Express
Gemma M0
Trinket M0
Run the installer! Since we bundle the SiLabs and FTDI drivers as well, you'll need to click through the license
Select which drivers you want to install, the defaults will set you up with just about every Adafruit board!
Blink
Now you can upload your first blink sketch!
Plug in the Gemma M0, Trinket M0, Metro M0 or Feather M0 and wait for it to be recognized by the OS (just takes a
few seconds). It will create a serial/COM port, you can now select it from the dropdown, it'll even be 'indicated' as
Trinket/Gemma/Metro/Feather M0!
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
}
And click upload! That's it, you will be able to see the LED blink rate change as you adapt thedelay() calls.
Sucessful Upload
If you have a successful upload, you'll get a bunch of red text that tells you that the device was found and it was
programmed, verified & reset
Compilation Issues
If you get an alert that looks like
Make sure you have installed the Arduino SAMD boards package, you need both Arduino & Adafruit SAMD board
packages
The red LED will pulse, so you know that its in bootloader mode.
Once it is in bootloader mode, you can select the newly created COM/Serial port and re-try uploading.
You may need to go back and reselect the 'normal' USB serial port next time you want to use the normal upload.
The fix for this issue is to make sure Adafruit's custom udev rules are applied to your system. One of these rules is
made to configure modem manager not to touch the Feather board and will fix the programming difficulty issue.
Follow the steps for installing Adafruit's udev rules on this page. (http://adafru.it/iOE)
The below note are for all M0 boards, but not all may apply (e.g. Trinket and Gemma M0 do not have ARef so you
can skip the Analog References note!)
Analog References
If you'd like to use the ARef pin for a non-3.3V analog reference, the code to use isanalogReference(AR_EXTERNAL) (it's
AR_EXTERNAL not EXTERNAL)
pinMode(pin, INPUT)
digitalWrite(pin, HIGH)
This is because the pullup-selection register is the same as the output-selection register.
pinMode(pin, INPUT_PULLUP)
Serial vs SerialUSB
99.9% of your existing Arduino sketches use Serial.print to debug and give output. For the Official Arduino
SAMD/M0 core, this goes to the Serial5 port, which isn't exposed on the Feather. The USB port for the Official
Arduino M0 core, is called SerialUSB instead.
In the Adafruit M0 Core, we fixed it so that Serial goes to USB when you use a Feather M0 so it will automatically
work just fine.
However, on the off chance you are using the official Arduino SAMD core not the Adafruit version (which
really, we recommend you use our version because as you can see it can vary) & you want your Serial
prints and reads to use the USB port, use SerialUSB instead of Serial in your sketch
If you have existing sketches and code and you want them to work with the M0 without a huge find-replace, put
right above the first function definition in your code. For example:
For all SAMD21 chips, there are two peripherals that can generate PWM signals: The Timer/Counter (TC) and
Timer/Counter for Control Applications (TCC). Each SAMD21 has multiple copies of each, called 'instances'.
Each TC instance has one count register, one control register, and two output channels. Either channel can be
enabled and disabled, and either channel can be inverted. The pins connected to a TC instance can output identical
versions of the same PWM waveform, or complementary waveforms.
Each TCC instance has a single count register, but multiple compare registers and output channels. There are
options for different kinds of waveform, interleaved switching, programmable dead time, and so on.
The biggest members of the SAMD21 family have five TC instances with two 'waveform output' (WO) channels, and
three TCC instances with eight WO channels:
TC[0-4],WO[0-1]
TCC[0-2],WO[0-7]
And those are the ones shown in the datasheet's multiplexer tables.
The SAMD21G used in the Feather M0 only has three TC instances with two output channels, and three TCC
instances with eight output channels:
TC[3-5],WO[0-1]
TCC[0-2],WO[0-7]
Tracing the signals to the pins broken out on the Feather M0, the following pins can't do PWM at all:
Analog pin A5
The following pins can be configured for PWM without any signal conflicts as long as the SPI, I2C, and UART pins
keep their protocol functions:
If only the SPI pins keep their protocol functions, you can also do PWM on the following pins:
#include <util/delay.h>
In which case you can simply locate where the line is (the error will give you the file name and line number) and
'wrap it' with #ifdef's so it looks like:
The above will also make sure that header file isn't included for other architectures
If the #include is in the arduino sketch itself, you can try just removing the line.
Bootloader Launching
For most other AVRs, clicking reset while plugged into USB will launch the bootloader manually, the bootloader will
time out after a few seconds. For the M0, you'll need to double click the button. You will see a pulsing red LED to let
you know you're in bootloader mode. Once in that mode, it wont time out! Click reset again if you want to go back to
launching code
uint8_t mybuffer[4];
float f = (float)mybuffer;
You can't be guaranteed that this will work on a 32-bit platform becausemybuffer might not be aligned to a 2 or 4-
byte boundary. The ARM Cortex-M0 can only directly access data on 16-bit boundaries (every 2 or 4 bytes). Trying
to access an odd-boundary byte (on a 1 or 3 byte location) will cause a Hard Fault and stop the MCU. Thankfully,
there's an easy work around ... just use memcpy!
uint8_t mybuffer[4];
float f;
memcpy(f, mybuffer, 4)
Unfortunately, the M0 run-time library does not have dtostrf. You may see some references to using#include
<avr/dtostrf.h> to get dtostrf in your code. And while it will compile, it doesnot work.
Instead, check out this thread to find a working dtostrf function you can include in your code:
http://forum.arduino.cc/index.php?topic=368720.0 (http://adafru.it/lFS)
int FreeRam () {
char stack_dummy = 0;
return &stack_dummy - sbrk(0);
}
That string is now in FLASH. You can manipulate the string just like RAM data, the compiler will automatically read
from FLASH so you dont need special progmem-knowledgeable functions.
You can verify where data is stored by printing out the address:
Serial.print("Address of str $"); Serial.println((int)&str, HEX);
If the address is $2000000 or larger, its in SRAM. If the address is between $0000 and $3FFFF Then it is in FLASH
Adafruit Express and Gemma/Trinket M0 boards feature an improved bootloader that makes it easier than ever to
flash different code onto the microcontroller. This bootloader makes it easy to switch between Microsoft MakeCode,
CircuitPython and Arduino.
Instead of needing drivers or a separate program for flashing (say,bossac, jlink or avrdude), one can simply drag a file
onto a removable drive.
The format of the file is a little special. Due to 'operating system woes' you cannot just drag a binary or hex file (trust
us, we tried it, it isn't cross-platform compatible). Instead, the format of the file has extra information to help the
bootloader know where the data goes. The format is called UF2 (USB Flashing Format). Microsoft MakeCode
generates UF2s for flashing and CircuitPython releases are also available as UF2. You can also create your own
UF2s from binary files using uf2tool, available here. (http://adafru.it/vPE)
The bootloader is also BOSSA compatible, so it can be used with the Arduino IDE which expects a BOSSA
bootloader on ATSAMD-based boards
For more information about UF2, you can read a bunch more at the MakeCode blog(http://adafru.it/w5A), then
check out the UF2 file format specification (http://adafru.it/vPE) and to build your own bootloader for ATSAMD-
based boards, visit Microsoft UF2-SAMD github repository (http://adafru.it/vPF).
The bootloader is not needed when changing your CircuitPython code. Its only needed when upgrading the
CircuitPython core or changing between CircuitPython, Arduino and Microsoft MakeCode.
Furthermore, when the bootloader is active, it will change the color of one or more onboard neopixels to indicate the
connection status, red for disconnected and green for connected. If the board is plugged in but still showing that its
disconnected, try a different USB cable. Some cables only provide power with no communication.
For example, here is a Feather M0 Express running a colorful Neopixel swirl. When the reset button is double
clicked (about half second between each click) the NeoPixel will stay green to let you know the bootloader is active.
When the reset button is clicked once, the 'user program' (NeoPixel color swirl) restarts.
That could mean that your USB cable is no good, it isn't connected to a computer, or maybe the drivers could not
enumerate. Try a new USB cable first. Then try another port on your computer!
Once the bootloader is running, check your computer. You should see a USB Disk drive...
You may also get get a complaint that the drive was ejected without warning. Don't worry about this. The drive only
ejects once the bootloader has verified and completed the process of writing the new code
Windows 7 Drivers
If you are running Windows 7 (or, goodness, something earlier?) You will need a Serial Port driver file. Windows 10
users do not need this so skip this step.
If you're running Windows, its a good idea to verify the device showed up. Open your Device Manager from the
control panel and look under Ports (COM & LPT) for a device called Feather M0 or Circuit Playground or
whatever!
If you see something like this, it means you did not install the drivers. Go back and try again, then remove and re-
plug the USB cable for your board
You can download the latest builds here. (http://adafru.it/s1B) The mingw32 version is for Windows, apple-darwin for
Mac OSX and various linux options for Linux. Once downloaded, extract the files from the zip and open the
command line to the directory with bossac
For example here's the command line you probably want to run:
bossac -e -w -v -R ~/Downloads/adafruit-circuitpython-feather_m0_express-0.9.3.bin
This will -erase the chip, -write the given file, -verify the write and -Reset the board. After reset, CircuitPython should
be running. Express boards may cause a warning of an early eject of a USB drive but just ignore it. Nothing
important was being written to the drive. A hard power-reset is also recommended after bossac, just in case.
Updating the bootloader is as easy as flashing CircuitPython, Arduino or MakeCode. Simply enter the bootloader as
above and then drag the update bootloader uf2 file below. This uf2 contains a program which will unlock the
bootloader section, update the bootloader, and re-lock it. It will overwrite your existing code such as CircuitPython or
Arduino so make sure everything is backed up!
After the file is copied over, the bootloader will be updated and appear again. TheINFO_UF2.TXT file should show
the newer version number inside.
For example:
Lastly, reload your code from Arduino or MakeCode or flash thelatest CircuitPython core (http://adafru.it/tBa).
Uncheck the box at the top, labeled Use Autoplay for all
devices
Once you have a .bin file, you simply need to run the Python conversion script over it. Here is an example from the
directory with uf2conv.py:
This will produce a revg.uf2 file in the same directory as the source revg.bin. The uf2 can then be flashed in the
same way as above.