Introduction To The Pyboard
Introduction To The Pyboard
To get the most out of your pyboard, there are a few basic things to
Because the pyboard does not have a housing it needs a bit of care:
- Static electricity can shock the components on the pyboard and destroy
them. If you experience a lot of static electricity in your area (eg dry and
cold climates), take extra care not to shock the pyboard. If your pyboard
came in a black plastic box, then this box is the best way to store and carry
the pyboard as it is an anti-static box (it is made of a conductive plastic,
with conductive foam inside).
As long as you take care of the hardware, you should be okay. It's almost
with writing code as much as you like. If the filesystem gets corrupt, see
below on how to reset it. In the worst case you might need to reflash the
The micro USB connector is on the top right, the micro SD card slot on
the top left of the board. There are 4 LEDs between the SD slot and
USB connector. The colours are: red on the bottom, then green, orange,
and blue on the top. There are 2 switches: the right one is the reset
switch, the left is the user switch.Plugging in and powering on
The pyboard can be powered via USB. Connect it to your PC via a micro
USB cable. There is only one way that the cable will fit. Once connected,
Be sure to connect the positive lead of the power supply to VIN, and
Let's jump right in and get a Python script running on the pyboard. After
There is only one way that the cable will connect, so you can't get it
wrong.
When the pyboard is connected to your PC it will power on and enter the
start up process (the boot process). The green LED should light up for half
a second or less, and when it turns off it means the boot process has
completed.
using Explorer.
Windows will also see that the pyboard has a serial device, and it will
Okay, so you should now have the pyboard connected as a USB flash drive,
and
a window (or command line) should be showing the files on the pyboard
drive.
The drive you are looking at is known as ``/flash`` by the pyboard, and
should contain
* `boot.py <http://micropython.org/resources/fresh-pyboard/boot.py>`_
-- the various configuration options for the pyboard.
* `main.py <http://micropython.org/resources/fresh-pyboard/main.py>`_
-- the Python program to be run.
This provides pointers for new users and can be safely deleted.
* `pybcdc.inf
<http://micropython.org/resources/fresh-pyboard/pybcdc.inf>`_ -- the
Windows driver file to configure the serial USB device.
Editing ``main.py``
-------------------
Now we are going to write our Python program, so open the ``main.py``
file in a text editor. On Windows you can use notepad, or any other editor.
On Mac and Linux, use your favourite text editor. With the file open you
will
lines will not do anything, and are there for you to write notes about your
program.
Let's add 2 lines to this ``main.py`` file, to make it look like this::
import pyb
pyb.LED(4).on()
The first line we wrote says that we want to use the ``pyb`` module.
This module contains all the functions and classes to control the features
of the pyboard.
The second line that we wrote turns the blue LED on: it first gets the
``LED``
class from the ``pyb`` module, creates LED number 4 (the blue LED), and
then
turns it on.
---------------------
To run this little script, you need to first save and close the ``main.py``
file,
and then eject (or unmount) the pyboard USB drive. Do this like you
would a
When the drive is safely ejected/unmounted you can get to the fun part:
press the RST switch on the pyboard to reset and run your script. The RST
switch is the small black button just below the USB connector on the
board,
When you press RST the green LED will flash quickly, and then the blue
Congratulations! You have written and run your very first MicroPython
program!
=================================
REPL stands for Read Evaluate Print Loop, and is the name given to the
interactive MicroPython prompt that you can access on the pyboard. Using
the REPL is by far the easiest way to test out your code and run
commands.
Windows
-------
You need to install the pyboard driver to use the serial USB device.
for your computer, find the pyboard in the list of devices (it should have
a warning sign next to it because it's not working yet), right click on
the pyboard device, select Properties, then Install Driver. You need to
then select the option to find the driver manually (don't use Windows auto
update),
navigate to the pyboard's USB drive, and select that. It should then install.
Please consult this guide if you are having problems installing the driver.
You now need to run your terminal program. You can use HyperTerminal
if you
`putty.exe
<http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html>`_.
Using your serial program you must connect to the COM port that you
found in the
previous step. With PuTTY, click on "Session" in the left-hand panel, then
click
the "Serial" radio button on the right, then enter you COM port (eg COM4)
in the
Mac OS X
--------
screen /dev/tty.usbmodem*
When you are finished and want to exit screen, type CTRL-A CTRL-\\.
Linux
-----
screen /dev/ttyACM0
You can also try ``picocom`` or ``minicom`` instead of screen. You may
have to
yourself the correct permissions to access this devices (eg group ``uucp``
or ``dialout``,
or use sudo).
---------------------
Now let's try running some MicroPython code directly on the pyboard.
With your serial program open (PuTTY, screen, picocom, etc) you may see
a blank
screen with a flashing cursor. Press Enter and you should be presented
with a
MicroPython prompt, i.e. ``>>>``. Let's make sure it is working with the
obligatory test::
hello pyboard!
In the above, you should not type in the ``>>>`` characters. They are
there to
indicate that you should type the text after it at the prompt. In the end,
once
you have entered the text ``print("hello pyboard!")`` and pressed Enter,
the output
If you already know some python you can now try some basic commands
here.
If any of this is not working you can try either a hard reset or a soft reset;
see below.
Go ahead and try typing in some other commands. For example::
>>> pyb.LED(1).on()
>>> pyb.LED(2).on()
>>> 1 + 2
>>> 1 / 2
0.5
>>> 20 * 'py'
'pypypypypypypypypypypypypypypypypypypypy'
-------------------
If something goes wrong, you can reset the board in two ways. The first is
to press CTRL-D
at the MicroPython prompt, which performs a soft reset. You will see a
message something like ::
>>>
>>>
switch (the small black button closest to the micro-USB socket on the
board). This will end your
=========================================
>>> myled.on()
>>> myled.off()
These commands turn the LED on and off.
This is all very well but we would like this process to be automated. Open
the file MAIN.PY on the pyboard in your favourite text editor. Write or
paste the following lines into the file. If you are new to python, then make
sure you get the indentation correct since this matters! ::
led = pyb.LED(2)
while True:
led.toggle()
pyb.delay(1000)
When you save, the red light on the pyboard should turn on for about a
second. To run the script, do a soft reset (CTRL-D). The pyboard will then
restart and you should see a green light continuously flashing on and off.
Success, the first step on your path to building an army of evil robots!
When you are bored of the annoying flashing light then press CTRL-C at
your terminal to stop it running.
So what does this code do? First we need some terminology. Python is an
object-oriented language, almost everything in python is a *class* and
when you create an instance of a class you get an *object*. Classes have
*methods* associated to them. A method (also called a member function)
is used to interact with or control the object.
The first line of code creates an LED object which we have then called led.
When we create the object, it takes a single parameter which must be
between 1 and 4, corresponding to the 4 LEDs on the board. The pyb.LED
class has three important member functions that we will use: on(), off()
and toggle(). The other function that we use is pyb.delay() this simply
waits for a given time in milliseconds. Once we have created the LED
object, the statement while True: creates an infinite loop which toggles the
led between on and off and waits for 1 second.
**Exercise: Try changing the time between toggling the led and turning on
a different LED.**
-----------------------
So far we have only used a single LED but the pyboard has 4 available.
Let's start by creating an object for each LED so we can control each of
them. We do that by creating a list of LEDS with a list comprehension. ::
If you call pyb.LED() with a number that isn't 1,2,3,4 you will get an error
message.
Next we will set up an infinite loop that cycles through each of the LEDs
turning them on and off. ::
n=0
while True:
n = (n + 1) % 4
leds[n].toggle()
pyb.delay(50)
Here, n keeps track of the current LED and every time the loop is executed
we cycle to the next n (the % sign is a modulus operator that keeps n
between 0 and 3.) Then we access the nth LED and toggle it. If you run
this you should see each of the LEDs turning on then all turning off again
in sequence.
One problem you might find is that if you stop the script and then start it
again that the LEDs are stuck on from the previous run, ruining our
carefully choreographed disco. We can fix this by turning all the LEDs off
when we initialise the script and then using a try/finally block. When you
press CTRL-C, MicroPython generates a VCPInterrupt exception. Exceptions
normally mean something has gone wrong and you can use a try:
command to "catch" an exception. In this case it is just the user
interrupting the script, so we don't need to catch the error but just tell
MicroPython what to do when we exit. The finally block does this, and we
use it to make sure all the LEDs are off. The full code is::
l.off()
n=0
try:
while True:
n = (n + 1) % 4
leds[n].toggle()
pyb.delay(50)
finally:
for l in leds:
l.off()
----------------
The yellow and blue LEDs are special. As well as turning them on and off,
you can control their intensity using the intensity() method. This takes a
number between 0 and 255 that determines how bright it is. The following
script makes the blue LED gradually brighter then turns it off again. ::
led = pyb.LED(4)
intensity = 0
while True:
led.intensity(intensity)
pyb.delay(20)
You can call intensity() on LEDs 1 and 2 but they can only be off or on. 0
sets them off and any other number up to 255 turns them on.
.. _pyboard_tutorial_switch:
==================================
The pyboard has 2 small switches, labelled USR and RST. The RST switch
from scratch, equivalent to turning the power off then back on.
The USR switch is for general use, and is controlled via a Switch object.
>>> sw = pyb.Switch()
Remember that you may need to type ``import pyb`` if you get an error
that
the name ``pyb`` does not exist.
>>> sw.value()
False
This will print ``False`` if the switch is not held, or ``True`` if it is held.
Try holding the USR switch down while running the above command.
There is also a shorthand notation to get the switch status, by "calling" the
switch object::
>>> sw()
False
Switch callbacks
----------------
The switch is a very simple object, but it does have one advanced feature:
run when the switch is pressed, and uses an interrupt. It's probably best
to start with an example before understanding how interrupts work. Try
>>> sw.callback(lambda:print('press!'))
This tells the switch to print ``press!`` each time the switch is pressed
down. Go ahead and try it: press the USR switch and watch the output on
your PC. Note that this print will interrupt anything you are typing, and
>>> sw.callback(lambda:pyb.LED(1).toggle())
This will toggle the red LED each time the switch is pressed. And it will
>>> sw.callback(None)
You can pass any function (that takes zero arguments) to the switch
callback.
... pyb.LED(1).toggle()
...
>>> sw.callback(f)
This creates a function called ``f`` and assigns it to the switch callback.
You can do things this way when your function is more complicated than a
Note that your callback functions must not allocate any memory (for
example
global variable (or make it local and close over it). If you need to do
a long, complicated calculation, then use the callback to set a flag which
-------------------------------
Let's step through the details of what is happening with the switch
sets up an external interrupt trigger (falling edge) on the pin that the
switch is connected to. This means that the microcontroller will listen
on the pin for any changes, and the following will occur:
1. When the switch is pressed a change occurs on the pin (the pin goes
stops execution, and saves its current state (pushes the registers on
the stack). This has the effect of pausing any code, for example your
get the function that you registered with ``sw.callback()`` and executes
it.
from the pause, this code does not notice that it was interrupted.
The above sequence of events gets a bit more complicated when multiple
interrupts occur at the same time. In that case, the interrupt with the
highest priority goes first, then the others in order of their priority.
Further reading
---------------
The accelerometer
=================
Here you will learn how to read the accelerometer and signal using LEDs
states like tilt left and tilt right.
The pyboard has an accelerometer (a tiny mass on a tiny spring) that can
be used
to detect the angle of the board and motion. There is a different sensor for
>>> accel.x()
This returns a signed integer with a value between around -30 and 30.
Note that
the measurement is very noisy, this means that even if you keep the board
perfectly still there will be some variation in the number that you measure.
Because of this, you shouldn't use the exact value of the x() method but
see if
it is in a certain range.
light = pyb.LED(3)
SENSITIVITY = 3
while True:
x = accel.x()
light.on()
else:
light.off()
pyb.delay(100)
We create Accel and LED objects, then get the value of the x direction of
the
then the LED turns on, otherwise it turns off. The loop has a small
``pyb.delay()``
``SENSITIVITY``. Try running this on the pyboard and tilt the board left
and right
you tilt the pyboard. HINT: You will need to rescale the values, intensity
goes
from 0-255.**
---------------------
The example above is only sensitive to the angle in the x direction but if
we
use the ``y()`` value and more LEDs we can turn the pyboard into a spirit
level. ::
accel = pyb.Accel()
SENSITIVITY = 3
while True:
x = accel.x()
if x > SENSITIVITY:
xlights[0].on()
xlights[1].off()
xlights[1].on()
xlights[0].off()
else:
xlights[0].off()
xlights[1].off()
y = accel.y()
if y > SENSITIVITY:
ylights[0].on()
ylights[1].off()
ylights[1].on()
ylights[0].off()
else:
ylights[0].off()
ylights[1].off()
pyb.delay(100)
We start by creating a tuple of LED objects for the x and y directions.
Tuples
are immutable objects in python which means they can't be modified once
they are
created. We then proceed as before but turn on a different LED for positive
and
negative x values. We then do the same for the y direction. This isn't
particularly sophisticated but it does the job. Run this on your pyboard and
you
should see different LEDs turning on depending on how you tilt the board.
===========================
impossible for you to break the pyboard by programming the wrong thing.
The first thing to try is to enter safe mode: this temporarily skips
If you have problems with the filesystem you can do a factory reset,
---------
3. While still holding down USR, press and release the RST switch.
4. The LEDs will then cycle green to orange to green+orange and back
again.
5. Keep holding down USR until *only the orange LED is lit*, and then let
6. The orange LED should flash quickly 4 times, and then turn off.
In safe mode, the ``boot.py`` and ``main.py`` files are not executed,
and so
the pyboard boots up with default settings. This means you now have
access
to the filesystem (the USB drive should appear), and you can edit
``boot.py``
----------------------------
you can't escape from, then you can reset the filesystem.
Resetting the filesystem deletes all files on the internal pyboard storage
3. While still holding down USR, press and release the RST switch.
4. The LEDs will then cycle green to orange to green+orange and back
again.
5. Keep holding down USR until *both the green and orange LEDs are lit*,
and
7. The red LED will turn on (so red, green and orange are now on).
8. The pyboard is now resetting the filesystem (this takes a few seconds).
10. You now have a reset filesystem, and are in safe mode.
=====================================
The pyboard is a USB device, and can configured to act as a mouse instead
To do this we must first edit the ``boot.py`` file to change the USB
configuration. If you have not yet touched your ``boot.py`` file then it
To enable the mouse mode, uncomment the last line of the file, to
If you already changed your ``boot.py`` file, then the minimum code it
import pyb
pyb.usb_mode('VCP+HID')
This tells the pyboard to configure itself as a VCP (Virtual COM Port,
ie serial port) and HID (human interface device, in our case a mouse)
Eject/unmount the pyboard drive and reset it using the RST switch.
Your PC should now detect the pyboard as a mouse!
----------------------------
We will first do this manually using the REPL prompt. Connect to your
pyboard using your serial program and type the following (no need to type
Your mouse should move 100 pixels to the right! In the command above
you
number 100 is telling the PC that the mouse moved 100 pixels in the x
direction.
... pyb.delay(d)
...
The first argument to the function ``osc`` is the number of mouse events
to send,
and the second argument is the delay (in milliseconds) between events.
Try
-------------------------------------
Now lets make the mouse move based on the angle of the pyboard, using
the
At the moment the pyboard is acting as a serial USB device and an HID (a
mouse).
You also can't edit your ``boot.py`` to get out of HID-mode and back to
normal
To get around this we need to go into *safe mode*. This was described in
2. While still holding down USR, press and release the RST switch.
3. The LEDs will then cycle green to orange to green+orange and back
again.
4. Keep holding down USR until *only the orange LED is lit*, and then let
5. The orange LED should flash quickly 4 times, and then turn off.
the pyboard boots up with default settings. This means you now have
access
to the filesystem (the USB drive should appear), and you can edit
``main.py``.
import pyb
switch = pyb.Switch()
accel = pyb.Accel()
hid = pyb.USB_HID()
pyb.delay(20)
Save your file, eject/unmount your pyboard drive, and reset it using the
RST
switch. It should now act as a mouse, and the angle of the board will
move
the mouse around. Try it out, and see if you can make the mouse stand
still!
You'll note that the y-axis is inverted. That's easy to fix: just put a
--------------------------------
If you leave your pyboard as-is, it'll behave as a mouse everytime you plug
it in. You probably want to change it back to normal. To do this you need
to first enter safe mode (see above), and then edit the ``boot.py`` file.
In the ``boot.py`` file, comment out (put a # in front of) the line with the
The Timers
==========
at specific intervals.
for internal use, and 5 and 6 are used for servo and ADC/DAC control.
>>> tim
Timer(4)
>>> tim.init(freq=10)
Now that it's initialised, we can see some information about the timer::
>>> tim
The information means that this timer is set to run at the peripheral
point it triggers an interrupt, and then starts counting again from 0. These
numbers are set to make the timer trigger at 10 Hz: the source frequency
Timer counter
-------------
So what can we do with our timer? The most basic thing is to get the
current value of its counter::
>>> tim.counter()
21504
Timer callbacks
---------------
The next thing we can do is register a callback function for the timer to
This should start the red LED flashing right away. It will be flashing
timer::
>>> tim.init(freq=20)
>>> tim.callback(None)
The function that you pass to callback must take 1 argument, which is
the timer object that triggered. This allows you to control the timer
to use the pyboard for other things while these timers are running.
----------------------------
You can use a timer to create a microsecond counter, which might be
useful when you are doing something which requires accurate timing.
We will use timer 2 for this, since timer 2 has a 32-bit counter (so
does timer 5, but if you use timer 5 then you can't use the Servo
The prescaler is set at 83, which makes this timer count at 1 MHz.
for timer 2. The period is set to a large number so that the timer
zero.
.. _pyboard_tutorial_assembler:
Inline assembler
================
assembly routines as a Python function, and you can call them as you
would
a normal Python function.
Returning a value
-----------------
@micropython.asm_thumb
def fun():
movw(r0, 42)
You can enter this in a script or at the REPL. This function takes no
arguments and returns the number 42. ``r0`` is a register, and the value
in this register when the function returns is the value that is returned.
Accessing peripherals
---------------------
@micropython.asm_thumb
def led_on():
movwt(r0, stm.GPIOA)
This has the effect of setting high all those pins on port A for which
the corresponding bit in ``r0`` is set. In our example above, the 13th
bit in ``r0`` is set, so PA13 is pulled high. This turns on the red LED.
Accepting arguments
-------------------
used, they must be named ``r0``, ``r1``, ``r2`` and ``r3`` to reflect
the registers
@micropython.asm_thumb
This performs the computation ``r0 = r0 + r1``. Since the result is put
3.
Loops
-----
The following example flashes the green LED. It flashes it ``r0`` times. ::
@micropython.asm_thumb
def flash_led(r0):
movwt(r1, stm.GPIOA)
# get the bit mask for PA14 (the pin LED #2 is on)
label(loop1)
# turn LED on
movwt(r4, 5599900)
label(delay_on)
sub(r4, r4, 1)
cmp(r4, 0)
bgt(delay_on)
movwt(r4, 5599900)
label(delay_off)
sub(r4, r4, 1)
cmp(r4, 0)
bgt(delay_off)
# loop r0 times
sub(r0, r0, 1)
label(loop_entry)
cmp(r0, 0)
bgt(loop1)
Further reading
---------------
Power control
=============
while True:
do_some_processing()
pyb.wfi()
.. _pyboard_quickref:
===============================
The below pinout is for PYBv1.1. You can also view pinouts for
`PYBv1.0 <http://micropython.org/resources/pybv10-pinout.jpg>`__
or `PYBLITEv1.0-AC <http://micropython.org/resources/pyblitev10ac-
pinout.jpg>`__
or `PYBLITEv1.0 <http://micropython.org/resources/pyblitev10-
pinout.jpg>`__.
.. image:: http://micropython.org/resources/pybv11-pinout.jpg
.. only:: latex
.. image:: http://micropython.org/resources/pybv11-pinout-800px.jpg
Below is a quick reference for the pyboard. If it is your first time working
with
.. toctree::
:maxdepth: 1
general.rst
tutorial/index.rst
---------------------
See :mod:`pyb`. ::
import pyb
----------------
import time
Internal LEDs
-------------
led.toggle()
led.on()
led.off()
Internal switch
---------------
sw.callback(lambda: pyb.LED(1).toggle())
-------------
p_out.high()
p_out.low()
Servo control
-------------
External interrupts
-------------------
Timers
------
tim.freq(0.5) # 0.5 Hz
tim.callback(lambda t: pyb.LED(1).toggle())
---------------------
rtc = RTC()
----------------------------
See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.Timer <pyb.Timer>`. ::
ch.pulse_width_percent(50)
----------------------------------
adc = ADC(Pin('X19'))
----------------------------------
See :ref:`pyb.Pin <pyb.Pin>` and :ref:`pyb.DAC <pyb.DAC>`. ::
dac = DAC(Pin('X5'))
-----------------
uart.write('hello')
SPI bus
-------
See :ref:`pyb.SPI <pyb.SPI>`. ::
spi.send('hello')
I2C bus
-------
``scl`` and ``sda`` pins instead of the bus name. For more details see
:ref:`machine.I2C <machine.I2C>`. ::
---------------------------------
Internal accelerometer
----------------------
accel = Accel()