Added the iBeacon samples. Added sms_callback(), cellular.shutdown,
signal(), ucryptolib, machine.WDT(), and relay.receive(my_callback).
Added xbee_connect(), updated Install the certificates.
Added modem_status, AT commands that do not work in
MicroPython, delete_bondings(), passkey_enter(), passkey_confirm
(), secure(), io_callbacks(), and receive_callback(rx_callback). Added
the security argument to config(). Noted Digi modified slicing.
Added Idle device from MicroPython and apin.read_u16().
Updated Initiate sleep from MicroPython for the non-cellular devices.
Updated Test the connection.
Removed PyCharm section.
Added Recover an XBee device.
Trademarks and copyright
Digi, Digi International, and the Digi logo are trademarks or registered trademarks in the United
States and other countries worldwide. All other trademarks mentioned in this document are the
property of their respective owners.
Information in this document is subject to change without notice and does not represent a
commitment on the part of Digi International. Digi provides this document “as is,” without warranty of
any kind, expressed or implied, including, but not limited to, the implied warranties of fitness or
merchantability for a particular purpose. Digi may make improvements and/or changes in this manual
or in the product(s) and/or the program(s) described in this manual at any time.
Warranty
To view product warranty information, go to the following website:
www.digi.com/howtobuy/terms
Customer support
Gather support information: Before contacting Digi technical support for help, gather the following
information:
Product name and model
Product serial number (s)
Digi MicroPython Programming Guide
2
Page 3
Firmware version
Operating system/browser (if applicable)
Logs (from time of reported issue)
Trace (if possible)
Description of issue
Steps to reproduce
Contact Digi technical support: Digi offers multiple technical support plans and service packages.
Contact us at +1 952.912.3444 or visit us at www.digi.com/support.
Feedback
To provide feedback on this document, email your comments to
Include the document title and part number (Digi MicroPython Programming Guide, 90002219 U) in
the subject line of your email.
techcomm@digi.com
Digi MicroPython Programming Guide
3
Page 4
Contents
Digi MicroPython Programming Guide
Reference material12
Which features apply to my device?
Use MicroPython
Access the MicroPython environment15
Enter MicroPython code15
Direct entry15
Exit MicroPython15
Display tools15
Coding tips15
Recover an XBee device16
MicroPython syntax
Colons18
After conditional statements and loop statements18
Indentations18
FORloop with one statement indented18
FOR loop with two statements indented19
Functions19
Function with arguments19
Errors and exceptions
Syntax error22
Example22
Name error22
Referencing a name that was not created22
Referencing a name from one function that was created in a different function22
OSError23
Socket errors23
ENOTCONN: Time out error23
ENFILE: No sockets are available23
ENXIO: No such device or address23
Digi MicroPython Programming Guide
4
Page 5
Keyboard shortcuts
Keyboard shortcuts25
Select a previously typed statement25
Differences between MicroPython and other programming languages
Memory management27
Variable types27
Syntax27
Curly braces and indentation28
Semicolons29
Increment operator29
Logical operators30
Develop applications on an XBee device
Space allocated to MicroPython32
Code storage32
Built-in modules embedded in XBee firmware (device flash)32
Source code in .py files (file system)32
Parsed and compiled code in .mpy files (file system)32
Executable code on MicroPython heap (device RAM)32
Compiled modules relocated from file system to device flash33
How to organize your code33
Run code at startup33
Monitor memory usage33
The gc module33
The micropython module34
Efficient coding36
Application evolution37
One-liners in the REPL37
Short blocks in paste mode37
Flash upload mode37
Modules stored as .py files37
Compiled modules stored as .mpy files38
Compiled modules via Flash upload mode38
Compiled modules embedded in device flash39
Digi modified slicing for bytes and strings operations39
XBee 3 Zigbee RF Module, XBee 3 802.15.4 RF Module, XBee 3 DigiMesh RF Module:42
Sleeping with AT commands43
Idle a device from MicroPython43
Enter and exit the idle state43
Poll for data while the device is idle44
Digi MicroPython Programming Guide
5
Page 6
Access the primary UART
How to use the primary UART47
sys.stdin limitations47
Example: read bytes from the UART47
Example: read the first 15 bytes from the UART48
REPL (Read-Evaluate-Print Loop) examples
Ctrl+A: Enter raw REPLmode50
Ctrl+B: Print the MicroPython banner50
Print the banner51
Print the banner and verify that the memory was not wiped51
Ctrl+C: Regain control of the terminal52
Ctrl+D: Reboot the MicroPython REPL52
Ctrl+E: Enter paste mode53
Paste one line of code53
Paste a code segment54
Ctrl+F: Upload code to flash54
Load code to flash memory55
Erase the code stored in flash memory55
Flash memory and automatic code execution56
Run stored code at start-up to flash LEDs56
Disable code from running at start up57
Ctrl+R: Run code in flash58
Enable code to run at start-up58
Perform a soft-reset or reboot59
Access file system in MicroPython
Modify file system contents61
uos.chdir(dir)61
uos.getcwd()61
uos.ilistdir([dir])61
uos.listdir([dir])61
uos.mkdir(dir)61
uos.remove(file)61
uos.rmdir(dir)61
uos.rename(old_path, new_path)61
uos.replace(old_path, new_path)62
uos.sync()62
uos.compile(source_file, mpy_file=None)62
uos.format()62
uos.hash([secure_file])62
Access data in files63
File object methods63
read(size=-1)63
readinto(b)64
readline(size=-1)64
readlines()64
write(b)64
seek(offset, whence=0)64
tell()64
flush()64
Digi MicroPython Programming Guide
6
Page 7
close()64
Import modules from file system64
Reload a module65
Compiled MicroPython files65
Send and receive User Data Relay frames
Constants67
Interfaces (always defined)67
Limits67
Methods67
relay.receive()67
relay.send(dest, data)67
Exceptions67
relay.callback(my_callback)67
Examples68
MicroPython libraries on GitHub
MicroPython modules
XBee-specific functions71
Standard modules and functions71
Discover available modules72
Machine module
Reset-cause74
Constants74
Random numbers74
Unique identifier74
Class PWM (pulse width modulation)74
Class ADC: analog to digital conversion75
Constructors75
Methods76
Sample program76
Class I2C: two-wire serial protocol77
Constructors77
General methods78
Standard bus operations methods78
Memory operations methods78
Sample programs79
Class Pin82
Class UART82
Test the UART interface82
Use the UARTclass83
Constructors83
Methods84
Constants84
Class WDT: watchdog timer85
Access the XBee device's I/O pins85
Use the Pin() constructor87
Use mode() to configure a pin87
Digi MicroPython Programming Guide
7
Page 8
Pin.DISABLED87
Pin.IN88
Pin.OUT88
Pin.ALT88
Pin.ANALOG89
Pin.OPEN_DRAIN and Pin.ALT_OPEN_DRAIN89
Use pull() to configure an internal pull up/down resistor89
Generic gap advertising and gap scanning samples106
Eddystone Beaconing samples106
iBeacon samples106
Troubleshooting107
Fewer advertisements than expected when usinggap_scan107
Cellular network configuration module
Configure a specific network interface109
class Cellular109
Constructors110
Cellular power and airplane mode method110
Verify cellular network connection method110
Cellular connection configuration method110
Send an SMS message method110
Receive an SMS message method111
Register an SMS Receive Callback method111
Cellular shutdown method111
RSRP/RSRQ reporting in MicroPython112
XBee module
AT commands that do not work in MicroPython114
class XBee on XBee Cellular Modem114
Constructors114
Methods114
XBee MicroPython module on the XBee 3 RFModules115
Functions115
atcmd()115
discover()115
receive()117
receive_callback(rx_callback)118
transmit()118
modem_status119
digi.cloud module
Create and upload data points122
class DataPoints122
Digi MicroPython Programming Guide
9
Page 10
Constructor122
Optional parameter122
Add a data point method122
Upload data to Digi Remote Manager method123
Check the status of a DataPoints object124
The life-cycle of a DataPoints object124
Delete a DataPoints object124
Receive a Data Service Device Request125
class device_request125
Use the read(size=-1) method126
Use the readinto(b) method126
Use the write(b) method126
Use the close() method126
Use the API Explorer to send Device Requests126
The ussl module
ussl on the XBee Cellular Modem129
Syntax129
Usage129
Use AWS IoT from MicroPython
Add an XBee Cellular Modem as an AWS IoT device131
Create a policy for access control131
Create a Thing132
Install the certificates134
Test the connection135
Publish to a topic137
Confirm published data138
Subscribe to updates from AWS138
Time module example:get the current time
Retrieve the local time141
Retrieve time with a loop141
Delay and timing quick reference142
Cellular network connection examples
Check the network connection144
Check network connection with a loop144
Check network connection and print connection parameters145
Socket examples
Sockets148
Basic socket operations: sending and receiving data, and closing the network connection148
Basic data exchange code sample148
Response header lines149
Specialized receiving: send received data to a specific memory location150
DNS lookup151
Digi MicroPython Programming Guide
10
Page 11
DNS lookup code output152
Set the timeout value and blocking/non-blocking mode152
Send an HTTPrequest and dump the response154
Socket errors154
ENOTCONN: Time out error154
ENFILE: No sockets are available155
ENXIO: No such device or address155
Unsupported methods155
I/O pin examples
Change I/O pins157
Print a list of pins157
Change output pin values:turn LEDs on and off158
Poll input pin values158
Check the configuration of a pin159
Check the pull-up mode of a pin160
Measure voltage on the pin (Analog to Digital Converter)162
SMS examples
Send an SMS message165
Send an SMS message to a valid phone number165
Check network connection and send an SMS message165
Send to an invalid phone number166
Receive an SMS message166
Sample code167
Receive an SMS message using a callback168
XBee device examples
Print the temperature of the XBee Cellular Modem170
Print the temperature of the XBee 3 Zigbee RF Module170
Print a list of AT commands171
xbee.discover() examples173
Handle responses as they are received173
Gather all responses into a list173
xbee.transmit() examples174
xbee.transmit() using constants174
xbee.transmit() using byte string174
Digi MicroPython Programming Guide
11
Page 12
Digi MicroPython Programming Guide
This guide introduces the MicroPython programming language by showing how to create and run a
simple MicroPython program. It includes sample code to show how to use MicroPython to perform
actions on a Digi device, particularly those devices with Digi-specific behavior. It also includes
reference material that shows how MicroPython coding can be used with Digi devices.
You can code MicroPython to transform cryptic readings into useful data, filter out excess
transmissions, directly employ modern sensors and actuators, and use operational logic to glue inputs
and outputs together in an intelligent way.
The XBee Cellular Modem has MicroPython running on the device itself. You can access a MicroPython
prompt from the XBee Cellular Modem when you install it in an appropriate development board (XBDB
or XBIB), and connect it to a computer via a USB cable.
Reference material
MicroPython is an open-source programming language based on the Python 3 standard library.
MicroPython is optimized to run on a microcontroller, cellular modem, or embedded system.
Refer to the Get started with MicroPython section of the appropriate user guide for information on
how to enter the MicroPython environment and several simple examples to get you started:
n Digi XBee PyCharm IDE Plugin User Guide
n Digi XBee Cellular Embedded Modem User Guide
n Digi XBee Cellular 3G Global Embedded Modem User Guide
n Digi XBee 3 Cellular LTE Cat 1 Smart Modem User Guide
n Digi XBee 3 Cellular LTE-M Global Smart Modem User Guide
n XBee 3 802.15.4 RF Module User Guide
n XBee 3 DigiMesh RFModule User Guide
n XBee 3 Zigbee RF Module User Guide
This programming guide assumes basic programming knowledge. For help with programming
knowledge, you can refer to the following sites for Python and MicroPython:
n MicroPython: micropython.org
n MicroPython documentation: docs.micropython.org
n MicroPython Wiki: wiki.micropython.org
n Python: python.org
Digi MicroPython Programming Guide
12
Page 13
Which features apply to my device?
MicroPython features and errors differ depending on the device you use. Unless specified, information
in this document applies to all devices. This table covers which features apply to specific products:
FeatureXBee 3 Cellular XBee 3 Zigbee, DigiMesh, and 802.15.4
Digital I/OYesYes
I2CYesYes
Power managementYesYes
Idle from MicroPythonNoYes
Digi Remote ManagerYes
Secondary UARTYesNo
Real-time clockYesNo
File systemYesYes
File system - concurrent file writesYesNo
File system - renameYesNo
File system - Edit files after creationYesNo
1
No
File System - deleteYesNo
File System - secure filesYesNo
File System preserved across updatesYesNo
1
Remote Manager features are only supported on XBee 3 Cellular devices, not XBee Cellular.
2
Files can be deleted, but doing so does not reclaim their space on the file system.
Digi MicroPython Programming Guide
2
13
Page 14
Use MicroPython
Access the MicroPython environment15
Enter MicroPython code15
Exit MicroPython15
Display tools15
Coding tips15
Recover an XBee device16
Digi MicroPython Programming Guide
14
Page 15
Use MicroPythonAccess the MicroPython environment
Access the MicroPython environment
To begin using MicroPython on the XBee device, open XCTU and enter MicroPython mode. See Use
XCTU to enter the MicroPython environment in the appropriate user guide.
Enter MicroPython code
You can use different methods to enter MicroPython code into the MicroPython Terminal on the XBee
device.
n Direct entry: Manually type code into the MicroPython Terminal.
n Paste mode: Use the REPL paste mode to paste copied code into the MicroPython Terminal for
immediate execution.
n Flash mode: Use the REPL flash mode to paste a block of code into the MicroPython Terminal
and store it in flash memory.
n Access file system in MicroPython: Upload code to the file system.
Direct entry
From a serial terminal, you can type code at the MicroPython REPL prompt. When you press Enter, the
line of code runs and another MicroPython prompt appears. Manually typing in code is the simplest
method.
Example
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, type print("This is a simple line of code") and then press
Enter. The phrase in quotes prints in the terminal: This is a simple line of code
Exit MicroPython
When you are done coding, exit MicroPython by closing the MicroPython terminal. Any code that has
been executed will continue to run, even if the XBee device is set to Transparent or API mode.
For additional instructions, see the Exit MicroPython mode section in the appropriate user guide.
Display tools
MicroPython mode requires echo to be turned off in terminal emulation. Command mode does not
echo your input back to you. In order to see what you are typing, use the appropriate display tool:
n MicroPython mode: For MicroPython coding, use the XCTU MicroPython Terminal or configure
your terminal emulator for "echo off."
n Command mode: For device configuration that is done in Command mode (initiated by sending
+++ to the device), use the XCTU Serial Console or configure your terminal emulator for "echo
on."
Coding tips
For all XBee devices:
Digi MicroPython Programming Guide
15
Page 16
Use MicroPythonRecover an XBee device
n Use tabs instead of spaces when indenting lines of code to minimize source code byte count.
n Use the integer division operator (//) unless you need a floating point.
n MicroPython's struct_time does not include the tm_isdst element in the tuple.
For the XBee Cellular Modem:
n The XBee Cellular Modem supports the use of hostnames in socket.connect() calls, unlike
other MicroPython platforms that require an IP address obtained by doing a manual look-up
using socket.getaddrinfo().
For the XBee 3 Zigbee RF Module:
n The Micropython time.time() function returns the number of seconds since the epoch. The
XBee 3 Zigbee RF Module does not have a realtime clock, so it does not support time.time().
To track elapsed time, use time.ticks_ms().
For XBee3 radio modules:
n The counter for the Micropython ticks_us() function will fall behind ticks_ms() by about 1 ms
every 10 seconds.
n If you need a high level of accuracy over a long period of time, use ticks_ms().
Recover an XBee device
If you are unable to communicate with an XBee device when a MicroPython script is running—for
example, if your MicroPython code is changing settings such as ATBD to strange values—you can
recover the XBee device by holding serial break—DIN line low—while the XBee is reset or powered up.
If serial break is held during reset/power-on, the XBee will enter Command mode at 9600 baud, and
MicroPython will not execute until Command mode is exited.
While in Command mode you can then set ATPS to 0 to disable MicroPython autostart, for example.
You can also query and set ATBD or other commands to assist in restoring communication with the
XBee.
Note See Break control for related information.
Digi MicroPython Programming Guide
16
Page 17
MicroPython syntax
Syntax refers to rules that must be followed when entering code into MicroPython. If you do not follow
the syntax rules when coding, errors are generated, and the code may not run as expected or not run
at all.
For information about coding errors, see Errors and exceptions.
The following sections describe coding syntax rules.
Colons18
Indentations18
Functions19
Digi MicroPython Programming Guide
17
Page 18
MicroPython syntaxColons
Colons
MicroPython requires a colon (:) after you entered the following statement types:
n Function name and the arguments that function accepts, if any
n Condition statement
n Loop statement
Defining a function
A function consists of the following:
n def keyword
n Function name
n Any arguments the function takes, inside a set of parentheses. The parentheses remain empty
if there are no passed arguments
n The function declaration must be followed by a colon
The code sample below is a basic function definition. Note that a colon is entered after the function
name. This colon defines the following indented lines as part of the function. Indentation is equally
important, and is discussed in Indentations.
def sample_function():
After conditional statements and loop statements
A colon is required after each conditional statement and loop statement. The code sample below
shows how the colon is used for a conditional statement (if True:) and for a loop statement (for x inrange(10):).
>if True:
for x in range(10):
Indentations
In MicroPython, an indentation tells the compiler which statements are members of a function,
conditional execution block, or a loop. If a line is not indented, that line is not considered a part of the
function, conditional execution block, or loop.
A function declaration, conditional execution block, or loop should be followed by a colon. All code after
the colon that is meant to be part of that block must be indented. For more information about how
colons are used in the code, see Colons.
print("I am a sample function!")
print("Condition is true!")
print("Current number: %d" % x)
FORloop with one statement indented
In this example, only one statement after the initial FORloop statement (which ends in a colon) is
indented. When the loop is executed, only line 2 of the code is executed. When the loop completes, the
code at line 3 executes.
Digi MicroPython Programming Guide
18
Page 19
MicroPython syntaxFunctions
When this code executes, it prints "In the FORloop, iteration # <number>" 10 times, where
<number> is 0 in the first loop of the code, and 9 at the last loop. Line 3 of the code runs one time,
after the loop completes, printing the phrase "Current number: 9" one time.
for x in range(10):
print("In the FOR loop, iteration # %d" % x)
print("Current number: %d" % x)
FOR loop with two statements indented
In this example, both statements after the initial FORloop statement (which ends in a colon) are
indented. When the loop is executed, both print statements are printed in each loop iteration.
As in the previous example, the code prints "In the FORloop, iteration # <number>", where
<number> is 0 in the first loop of the code, and 9 at the last loop. This time, however, line 3 of the code
is run in each loop iteration, and prints the phrase "Current number: number". Both phrases are
printed 10 times, with the <number> starting at 0 and increasing by one on each loop.
for x in range(10):
print("In the FOR loop, iteration # %d" % x)
print("Current number: %d" % x)
Functions
A function is an operation that performs an action and may return a value. A function consists of the
following:
n def keyword. The def keyword is required, and is short for "define".
n Function name.
n Any arguments the function takes, defined by a set of parentheses. The parentheses remain
n The function statement must be followed by a colon. For more information, see Colons.
The code sample below is a basic function definition. Note that the colon is entered after the function
name and parentheses. This colon defines that everything after that line that is indented is part of the
function. Indentation is equally important, and is discussed in the Indentations section.
Function with arguments
This sample shows how to define a function and then how to call the function to perform an operation
and return a value.
n Line 1: Define the function and define two arguments: x and y.
n Line 2: Define the variable that holds the sum of the arguments as sum_val.
n Line 3: Define a phrase that will be printed to the terminal including sum_val .
n Line 4: The function returns the value of its own variable sum_val. A returned value can be
n Line 6: Define the value of the variable global_sum to be the value returned by the function
empty if there are no passed arguments.
def example_function():
print("I am a function!")
used and stored outside of the function.
Digi MicroPython Programming Guide
19
Page 20
MicroPython syntaxFunctions
defined in line 1: addition_function(3,4), which is equal to the returned variable sum_val.
n Line 7: Define that a phrase that includes global_sum is printed to the terminal.
def addition_function(x,y):
sum_val = x + y
print("value of sum (x+y): %d" % sum_val)
return sum_val
global_sum = addition_function(3,4)
print("Value of global_sum: %d" % global_sum)
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
Digi MicroPython Programming Guide
20
Page 21
Errors and exceptions
If something goes wrong during compilation or during execution of code you have entered, you may
get an error. The type of error that occurred and the line number that caused the error will print to
the terminal. Errors can happen for many reasons, such as syntax errors, name errors (which
generally means the variable or function you are referencing is not available), or other more specific
errors.
Note Some exceptions have Error in their name and others have Exception.
Common types of errors include:
Syntax error22
Name error22
OSError23
Socket errors23
Digi MicroPython Programming Guide
21
Page 22
Errors and exceptionsSyntax error
Syntax error
A syntax error occurs when a MicroPython code statement has the wrong syntax.
Example
In this example, the syntax is incorrect. A colon is missing after the word "True".
if True print("Condition is true!")
When you press Enter to run the code it generates the following Exception describing the error
(SyntaxError) and the execution path that led to it (line 1 of the code you entered).
Traceback (most recent call last):
File "<stdin>", line 1
SyntaxError: invalid syntax
The correct code syntax is:
if True: print("Condition is true!")
Name error
Aname error is generated when a name of an item, such as a variable or function, cannot be found.
This can occur when:
n You typed the name into the code incorrectly.
n You are referencing a name that was never created.
n The name is defined, but is not in scope when you reference it. For example, if you defined the
name in function A, but are referencing the name in function B.
Referencing a name that was not created
In this example, the name deviation_factor was not created. If you reference this name in the code, a
NameError occurs in line 4, as the code references the deviation_factor name, which was not
created.
print("Assigning value to x...")
x = 17
print("Adding deviation_factor to x...")
x = x + deviation_factor
Referencing a name from one function that was created in a
different function
In this example, a variable is created in the example_func. When you run the code, the NameError
references line 8, where the code tries to print local_variable. The variable was created inside the
function example_func, and the scope of that variable, meaning where it can be accessed, is in that
function. The code references local_variable outside of that function.
def example_func():
print("Entering example function...")
local_variable = "I'm a variable inside this function"
Digi MicroPython Programming Guide
22
Page 23
Errors and exceptionsOSError
print(local_variable)
example_func()
print(local_variable)
OSError
MicroPython returns an OSError when a function returns a system-related error.
For example, if you try to send a message on a Zigbee network:
import xbee
xbee.transmit(xbee.ADDR_COORDINATOR, 'Hello!')
This code assumes that the device is associated to a network and able to send and receive data.
If the device is not associated with a network, it produces an OS error:
OSError: [Errno 7107] ENOTCONN.
Socket errors
Note This section only applies to the XBee Cellular Modem. See Which features apply to my device? for
a list of the supported features.
This following socket errors may occur.
ENOTCONN: Time out error
If a socket stays idle too long, it will time out and disconnect. Attempting to send data over a socket
that has timed out produces the OSError ENOTCONN, meaning "Error, not connected." If this
happens, perform another connect() call on the socket to be able to send data again.
ENFILE: No sockets are available
The socket.socket() or socket.connect() method returns an OSError (ENFILE) exception if no sockets
are available. If you are already using all of the available sockets, this error may occur in the few
seconds between calling socket.close() to close a socket, and when the socket is completely closed
and returned to the socket pool.
You can use the following methods to close sockets and make more sockets available:
n Close abandoned sockets: Initiate garbage collection (gc.collect()) to close any abandoned
MicroPython sockets. For example, an abandoned socket could occur if a socket was created in
a function but not returned. For information about the gc module, see the MicroPython
garbage collection documentation.
n Close all allocated sockets: Press Ctrl+D to perform a soft reset of the MicroPython REPL to
close all allocated sockets and return them to the socket pool.
ENXIO: No such device or address
OSError(ENXIO) is returned when DNS lookups fail from calling usocket.getaddrinfo().
Digi MicroPython Programming Guide
23
Page 24
Keyboard shortcuts
This section includes keyboard shortcuts you can use to make coding with MicroPython easier.
Keyboard shortcuts25
Select a previously typed statement25
Digi MicroPython Programming Guide
24
Page 25
Keyboard shortcutsKeyboard shortcuts
Keyboard shortcuts
XCTU version 6.3.6.2 and higher works when the REPL is enabled. The MicroPython Terminal tool
allows you to communicate with the MicroPython stack of your device through the serial interface.
The MicroPython Terminal tool in XCTU supports the following control characters:
Ctrl+A: Enter raw REPLmode. This is like a permanent paste mode, except that characters are not
echoed back.
Ctrl+B: Print the MicroPython banner. Leave raw mode and return to the regular REPL (also known as
friendly REPL). Reprints the MicroPython banner followed by a REPLprompt.
Ctrl+C: Regain control of the terminal. Interrupt the currently running program.
Ctrl+D: Reboot the MicroPython REPL. Soft-reset MicroPython, clears the heap.
Ctrl+E: Enter paste mode. Does not auto-indent and compiles pasted code all at once before
execution. Uses a REPL prompt of ===. Use Ctrl-D to compile uploaded code, or Ctrl-C to abort.
Ctrl+F: Upload code to flash. Uses a REPL prompt of ^^^. Use Ctrl-D to compile uploaded code, or Ctrl-
C to abort.
Ctrl+R: Run code in flash. Run code compiled in flash.
Note If PS is set to 1, code in flash automatically runs once at startup. Use Ctrl-R to re-run it.
Select a previously typed statement
You can use the UP and DOWN arrows on the keyboard to display a previously typed statement at the
current MicroPython prompt.
Note This shortcut does not work: (1) while in paste mode (Ctrl-E) or on any code entered while in
paste mode and (2) while in flash upload mode.
Arrow keys work to scroll back through previous commands, and to edit the current command. Some
terminal emulators (like CoolTerm) might not work with scrollback.
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, type print("statement 1") and press Enter.
3. At the MicroPython >>> prompt, type print("statement 2") and press Enter.
4. At the MicroPython >>> prompt, type print("statement 3") and press Enter.
5. At the MicroPython >>> prompt, press the UParrow key on the keyboard. The most recently
typed statement displays at the prompt. In this example, the statement print("statement 3")
displays.
6. You can press the UParrow key on the keyboard to display the next most recently type
statement, or press the DOWN arrow key on the keyboard to return the previously selected
statement. Continue this process until the statement you want to use displays at the
MicroPython >>> prompt. Use the Left and Right arrow keys and Backspace to make edits to
the previous statement if desired.
7. Press Enter to execute the displayed statement.
Digi MicroPython Programming Guide
25
Page 26
Differences between MicroPython and other
programming languages
You may have experience coding in another language, such as C or Java. You should be aware of the
coding differences between other languages and MicroPython.
Memory management27
Variable types27
Syntax27
Digi MicroPython Programming Guide
26
Page 27
Differences between MicroPython and other programming languagesMemory management
Memory management
In C, memory has to be allocated by the user for a variable or object before it can be used.
For a variable in C, this is done by a declaration statement as shown in the code below. The first 2
lines create a floating-point (decimal-valued real number) type variable named salary and an integer
named x. The last 2 lines assign values to each of those variables.
float salary;
int x;
x = 9;
salary = 3.0 + x;
In MicroPython, a variable does not need to be declared before it can be used. For example, the
MicroPython code shown below does the same thing as the C code shown in the example above. Each
line does multiple things: creates the variable (the name), assigns it a type based on the assigned
value, determines the space it needs in memory and allocates that space, and then assigns the value
to it.
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
x = 9
salary = x + 3.0
Variable types
In C, variables are "statically typed", meaning they are a certain type when they are created, and the
type does not change. This also means the variable can only hold data appropriate for the type.
In the C code sample shown below, an integer type variable named my_variable is created. An
integer type variable can only hold integer values and the amount of memory allocated to this variable
for storing its value is a fixed size- 4 bytes, limiting the range of values to -2,147,483,648 to
2,147,483,647 for a signed integer.
In MicroPython, variables are dynamically (or automatically) assigned a variable type when the user
assigns a value to the variable. In the code shown below, the variable big_number is assigned an
integer type, allocated the appropriate amount of memory, and the value stored after the user
assigns a value to the variable.
big_number = 99999999999999999999
If a user changes the value of the variable to a text string, MicroPython stores the string and
automatically changes the variable type to string.
int my_variable;
my_variable = 32;
big_number = "This is a really big number!"
Syntax
Syntax refers to rules that you must follow when programming. The following sections explain the
differences in syntax between MicroPython and other programming languages.
Digi MicroPython Programming Guide
27
Page 28
Differences between MicroPython and other programming languagesSyntax
Curly braces and indentation
In C, a function or conditional statement is enclosed by curly braces, as shown in the code sample
below.
void action1(void) {
printf("Function action1\n");
}
void action2(void) {
printf("Function action2\n");
}
if condition {
action1();
}
else {
action2();
}
In MicroPython, only a colon is required. Any statements that are part of the function must be
indented. The C code sample shown above would be coded in MicroPython as shown below. After the
function definitions and conditionals, the code to be executed is indented to make it a part of that
block. Indentation is used in MicroPython to tell the compiler which lines are members of a certain
structure.
def action1():
print("Function action1")
def action2():
print("Function action2")
if condition:
action1()
else:
action2()
In C, all of the instructions to be executed for the function some_function() are contained within the
curly braces. Most programmers indent all the instructions within the function for readability, but this
is not required for the code to work.
void some_function(void) {
int x;
x = 7;
x = x + 1;
printf("Incremented x!\n");
x = x + 2;
printf("Incremented x by 2!\n");
}
In MicroPython, indentation is required to tell the compiler what lines of code are to be executed for
the function some_function(), as shown in the example below.
Digi MicroPython Programming Guide
28
Page 29
Differences between MicroPython and other programming languagesSyntax
def some_function():
x = 7
x = x + 1
print("Incremented x!")
x = x + 2
print("Incremented x by 2!")
When nesting conditions and functions, C relies on curly braces, as shown in the example below. Each
level of code is indented to make it more readable, but it is not required for the code to run.
void some_other_function(void) {
if (condition) {
do_something();
}
}
In MicroPython, indentation is the only thing telling the compiler what instructions belong to what
function or condition. The nested C code example shown above is coded in MicroPython in the example
below:
def some_other_function():
if condition:
do_something()
Semicolons
Statements in C are followed by a semicolon, as shown in the example below.
int x;
x = 7 + 3;
action1();
In MicroPython, statements are ended by starting a new line. A special symbol or character is not
needed.
x = 7 + 3
action1()
Increment operator
C and Java have an "increment" operator, which lets the user increase the value of a variable by 1.
See the following excample:
int x;
x = 1;
x++;// x is now 2
x++;// x is now 3
MicroPython does not have an "increment" operator. To do the equivalent in MicroPython the variable
would have to have 1 explicitly added to it, or use the += operator.
The += operator states that a variable equals itself plus a value. So, in the MicroPython code block
below, line 3 is basically shorthand for line 2. They both do the same operation: set x equal to x plus 1.
x = 1
x = x + 1# x is now 2
x += 1# x is now 3
Digi MicroPython Programming Guide
29
Page 30
Differences between MicroPython and other programming languagesSyntax
Logical operators
In C, the logical operators AND, OR, and NOT are represented by &&, ||, and ! respectively. The C code
block below shows the logical operators in use.
// if it's sunny out, AND NOT cold outside
if (sunny_outside && !cold_outside) {
// if you have a towel AND an umbrella
if (have_towel && have_umbrella) {
// if you have a bike OR a car
if (have_bike || have_car) {
// then you will go to the beach
go_to_beach();
}
}
}
In MicroPython, the operators for AND, OR, and NOT are simply and, or, and not, which is much more
intuitive. The MicroPython code shown below has the same function as the C code shown above.
if sunny_outside and not cold_outside:
if have_towel and have_umbrella:
if have_bike or have_car:
go_to_beach()
Digi MicroPython Programming Guide
30
Page 31
Develop applications on an XBee device
Space allocated to MicroPython32
Code storage32
How to organize your code33
Run code at startup33
Monitor memory usage33
Efficient coding36
Application evolution37
Digi modified slicing for bytes and strings operations39
Digi MicroPython Programming Guide
31
Page 32
Develop applications on an XBee deviceSpace allocated to MicroPython
Space allocated to MicroPython
The XBee device allocates space in various locations for use by MicroPython.
n Heap (32 kB of RAM): Area used for variables, objects and modules imported from.py and.mpy
files in the file system.
n Stack (4 kB of RAM): RAM used by the MicroPython interpreter/task running as part of the XBee
firmware. If your function has tail recursion, try to rewrite it as a loop to reduce stack use.
n File System: Storage area for.pyand.mpy files, along with SSL/TLS certificates and other data
files.File system is managed usingATFS commands, the MicroPythonos module, and XCTU.
n Frozen/bundled.mpy files(32 kB of device flash): Storage area for compiled modules that can
execute in place.Standard MicroPython builds for other hardware (like the pyboard) refer to
these as "frozen".mpy files but only support embedding them into the firmware at compiletime. The XBee device adds anos.bundle()method to freeze multiple.mpy files into the
device flash so they can execute in place with a minimal impact on heap.
Note On XBee 3 Cellular devices with firmware ending in *15 or newer, the MicroPython heap has
been increased to 64 kB and the MicroPython stack has been increased to 6 kB of RAM.
Code storage
The XBee device stores code in different formats.
Built-in modules embedded in XBee firmware (device flash)
Many of the modules you import into your program are actually implemented in compiled C code that
exists as part of the MicroPython interpreter embedded in the XBee firmware and stored on the XBee
device's flash. These modules only use heap space for variables and any objects you instantiate, like a
machine.Pin() or network.Cellular() object.
Source code in .py files (file system)
You can create MicroPython modules and store them as .py files on the file system of the XBee
device's SPI flash. Upload the modules over the serial port via YMODEM protocol using XCTU or a
standard terminal emulator. When you import one of these files, MicroPython has to parse and
compile it to a form that it can execute from the heap.
Parsed and compiled code in .mpy files (file system)
Parsing and compiling MicroPython source code requires heap space, and larger programs require
more space than is available on the XBee device. XBee devices include the os.compile() method for
compiling a .py file into a .mpy file. The maximum size for compiling a .py file on the device depends
on its contents, but you may run out of memory trying to compile a 13 kB or larger file. In those cases,
you can use mpy-cross on a PC (Mac, Linux, Windows) to pre-compile your source code and upload the
resulting .mpy file instead.
Executable code on MicroPython heap (device RAM)
When you enter code in the REPL or import a module from the file system (a .py or .mpy file),
MicroPython places it in the heap where it can execute in place. See documentation for the gc and
micropython modules for methods to report on heap memory usage.
Digi MicroPython Programming Guide
32
Page 33
Develop applications on an XBee deviceHow to organize your code
Compiled modules relocated from file system to device flash
Use os.bundle() to freeze/embed multiple .mpy files to an area of the XBee device's internal flash
where they can execute in place. This can free up heap space for use by the running program.
How to organize your code
To create the lib directory, format your device. The main execution program is always called main.py
and should be located in /flash.
The modules and libraries you import should be located in /flash or /flash/lib.
You can load files using XCTU, any YMODEM compliant client or using PyCharm. PyCharm is the most
user friendly for developers.
When you manually load files onto an XBee3 device for the first time, the MicroPython interpreter
prompts you to format the file system. XCTU formats the files ystem using the AT FS FORMAT
command, and then you can download the files to the device using XCTU or the tools mentioned
above.
Run code at startup
If you configurethe PS (Python Startup) command = 1, the XBee device automatically tries to
run/flash/main.py or/flash/main.mpy (in that order) when the XBee device powers up or resets.It
also tries to run that code after a soft reboot—for example, viaCTRL-D in the "friendly" REPL but not
the "raw" REPL, or callingmachine.soft_reset()in your code.During development, you can useCTRL-Rto run the code as often as you'd like (for testing purposes), but if you replace/flash/main.py
or/flash/main.mpy using a method other than Flash Upload Mode (for example, YMODEM upload),
you will have to reset the REPL for it to reload code from those files.Each time you pressCTRL-R it
tells you if you are loading new code—and whether it is usingmain.py ormain.mpy—or just running
the same code as the last time you pressedCTRL-R.
As you can see above, it loaded from/flash/main.mpy the first time, but the second time it re-ran the
same code.
Monitor memory usage
MicroPython provides various tools you can use to monitor memory usage in the heap (RAM allocated
for MicroPython's use).
n The gc module
n The micropython module
The gc module
You canimport gc for tools to initiate garbage collection (deletion of objects on the heap no longer in
use) and measure heap usage.Usegc.mem_free() andgc.mem_alloc()for counts of available and
used memory. The two values should always add up to the same number.Due to the overhead
Digi MicroPython Programming Guide
33
Page 34
Develop applications on an XBee deviceMonitor memory usage
required by heap management, the 32 kB heap (32,768 bytes) only has 32,000 bytes available for
allocation.
Usegc.collect() to force garbage collection of unreferenced objects in the heap.You should always do
this before callinggc.mem_free() orgc.mem_alloc() in order to get an accurate value, or between
successive calls to see how much space was released.
You canimport micropython to get detailed information on heap memory usage, beyond the
summaries provided bygc.mem_free() andgc.mem_alloc().
micropython.mem_info()
Calling mem_info() without any parameters prints a summary of heap usage.Calling it with a
parameter—for example,micropython.mem_info(1)—adds a detailed report of memory usage on
the heap.Each line of the report starts with a memory offset into the heap, and then 64 characters
representing 16-byte blocks with the following meanings:
CharacterDescription
.unused (available) block
hstart (head) of an allocation (unknown content)
=continuation of allocation
Astart of array or bytearray
Bstart of function/bytecode
Dstart of dict
Fstart of float
Lstart of list
Mstart of module
Sstart of string or bytes
Tstart of tuple
The example below shows heap usage before and after importing a module (urequests) stored as
anmpy file on the XBee device.
Digi MicroPython Programming Guide
34
Page 35
Develop applications on an XBee deviceMonitor memory usage
>>> import micropython
>>> micropython.mem_info()
stack: 596 out of 3584
GC: total: 32000, used: 688, free: 31312
No. of 1-blocks: 9, 2-blocks: 14, max blk sz: 3, max free sz: 1950
>>> micropython.mem_info(1)
stack: 596 out of 3584
GC: total: 32000, used: 688, free: 31312
No. of 1-blocks: 9, 2-blocks: 14, max blk sz: 3, max free sz: 1950
GC memory layout; from 20001d10:
MicroPython stores identifiers (the names of things in your code– variables, methods, classes, and so
forth) in pools as "QSTR" objects.In doing so, it can reference the full QSTR in bytecode by using a 16-
Digi MicroPython Programming Guide
35
Page 36
Develop applications on an XBee deviceEfficient coding
bit index into the pool.The XBee firmware has a static QSTR pool embedded in it with names of builtin modules and their identifiers.Any Python code that runs on the XBee device can reference those
existing names in its compiled bytecode.New identifiers go into dynamic QSTR pools allocated in
MicroPython's heap.
You can use theqstr_info() method to report on the contents of those allocated pools.Without a
parameter, you will just see summary usage information.With a parameter, it prints the contents of
each QSTR stored in the pool.
Information reported by micropython.qstr_info()
n_poolnumber of QSTR pools allocated
n_qstrnumber of QSTRs allocated
n_str_data_bytescombined size of QSTR contents
n_total_bytestotal bytes used by the QSTR contents and pool overhead
At the beginning of the following example, MicroPython has not allocated any QSTR pools.In importing
a module (urequests) stored as an mpyfile on the XBee device, MicroPython allocated two pools,
totaling 50 strings of 464 bytes and using a total of 736 bytes of the heap.
Follow recommendations from the MicroPython documentation on Maximising MicroPython Speed.
Digi MicroPython Programming Guide
36
Page 37
Develop applications on an XBee deviceApplication evolution
Feel free to use docstrings (string literals used to document code) in your programs, as the parser will
ignore them and they are not included in compiled code or the.mpy file generated from the.py
source.
Application evolution
As you work on your MicroPython application, you will likely take portions of it though a series of
versions as it evolves from incomplete code (undergoing active development and debugging) to
feature-complete, debugged modules that rarely change.The following topics provide some
techniques you will use along the way to creating a production-ready application.If you are not
already familiar with the Python concept of modules, you can learn about them at
https://docs.python.org/3/tutorial/modules.html.
One-liners in the REPL
If you just want to test the syntax of a few lines of code, experimenting in the REPL (and even a
Python3 interpreter on your PC) can be a good place to start.
Short blocks in paste mode
If you are working on a multi-line sequence or a complete function, you might do so in an editor on
your computer, copy it to your clipboard, press Ctrl+E in the MicroPython REPL, paste the code, and
then pressCtrl+Dfor immediate execution.
Flash upload mode
Flash upload mode is similar to paste mode, but stores the compiled code so you can run it more than
once or automatically run it at startup.Press Ctrl+Fin the MicroPython REPL, paste the code, and
then press Ctrl+D to compile it.It stores the compiled code in/flash/main.mpy and you can then run
it by pressingCtrl+R.SetATPS = 1 to automatically run that code at startup.Flash upload mode
prompts you about changing the currentATPS value; you can pressEnter to accept the default of
leaving it unchanged.
Storing compiled code requires the file system be formatted first, if the file system is not formatted,
then the following error is generated: OSError: [Errno 7019] ENODEV
You can use the following method to format the file system from within MicroPython:
import os
os.format()
Note When uploading code through flash upload mode, /flash/main.mpy will be deleted if it already
exists. On file systems that do not support deleting files (see Which features apply to my device?), the
space used by the existing /flash/main.mpy file is not reclaimed. While developing using flash upload
mode on these devices, you may have to reformat the device if it runs out of space.
Modules stored as .py files
When you have a collection of related functions, you will probably want to combine them into a module
that you canimport into your main program and other modules.If you are going through lots of
revisions, it might be easiest to edit a.pyfile on your computer and then upload it to the XBee device
using XCTU or another terminal program.If you have previously loaded the module in MicroPython
with theimport statement, you need to perform a soft-reboot (press Ctrl+D at a REPL prompt) or use
the following methodto delete the old module and re-import it:
Digi MicroPython Programming Guide
37
Page 38
Develop applications on an XBee deviceApplication evolution
import sys
def reload(mod):
mod_name = mod.__name__
del sys.modules[mod_name]
return __import__(mod_name)
After running that code, you can type reload(foo) at a REPL prompt to reload a module from foo.py or
foo.mpy.
Compiled modules stored as .mpy files
At some point, you may not have enough space in the MicroPython heap to compile and load multiple
modules.In that case, you can pre-compile each.py file to a.mpy file to reduce the memory
requirements of animport statement.Use theos.compile() method to create a.mpy file on the XBee
device itself, or installmpy-cross on your PC and do it there before uploading to the XBee device.Withmpy-cross, you will have the added benefit of identifying syntax errors on your computer before
spending time uploading the file to the device.
Theos.compile() process prints memory usage information to help identify when you are reaching
the limitation of the XBee device's heap.In the example below, you can see that the parsing
ofurequests.pyrequires 7696 bytes (8336 - 640).The compilation step converts the parsed Python
source code to compiled bytecode, and is usually the most memory-intensive step of creating thempy
file.But once it is complete, garbage collection releases most of that temporarily allocated memory
and you see just the 3248 bytes (3888 - 640) required for the compiled code.
The final step saves the compiled module to the file system, but as you can see from the
finalgc.mem_alloc() call, there is still 608 bytes (1248-640) of heap in use.This is from the QSTR pools
created when parsing and compiling the code.Since QSTR pools are permanent, the only way to
recover that memory is to perform a soft reboot of the MicroPython REPL usingCtrl+D.
>>> import os
>>> os.chdir('lib')
>>> import gc
>>> gc.collect()
>>> gc.mem_alloc()
640
>>> os.compile('urequests.py')
stack: 644 out of 3584
GC: total: 32000, used: 640, free: 31360
No. of 1-blocks: 11, 2-blocks: 6, max blk sz: 8, max free sz: 1909
Parsing urequests.py...
stack: 644 out of 3584
GC: total: 32000, used: 8336, free: 23664
No. of 1-blocks: 19, 2-blocks: 11, max blk sz: 89, max free sz: 1407
Compiling...
stack: 644 out of 3584
GC: total: 32000, used: 3888, free: 28112
No. of 1-blocks: 44, 2-blocks: 34, max blk sz: 45, max free sz: 1225
Saving urequests.mpy...
>>> gc.collect()
>>> gc.mem_alloc()
1248
Compiled modules via Flash upload mode
A quick way to compile a module without having to use YMODEM is to use Flash upload mode, which
saves the pasted code as/flash/main.mpy, and then useos.replace('/flash/main.mpy',
Digi MicroPython Programming Guide
38
Page 39
Develop applications on an XBee deviceDigi modified slicing for bytes and strings operations
'/flash/lib/foo.mpy') to replace the oldmodule foo compiled code. This can only be done on modules
that support renaming files—see Which features apply to my device?.
Compiled modules embedded in device flash
You can maximize your application size by writing your code as modules, cross-compiling them on a
PC, uploading to the XBee device and then usingos.bundle() to freeze/embed them into the flash
where they can run in-place, with minimal heap usage.
Callos.bundle() without any parameters to get a list of modules embedded in the
flash.Callos.bundle(None) to erase the modules embedded in the flash.
MicroPython v1.9.4-803-g4b0a8eada-dirty on 2018-06-21; XBC LTE Cat 1 Verizon with
EFM32G
Type "help()" for more information.
>>> import os
>>> os.bundle()
['urequests', 'umqtt/simple']
>>> os.bundle(None)
Erased bundled modules.
>>> os.bundle()
[]
Callos.bundle('mod1.mpy', 'mod2.mpy', 'package/mod3.mpy') to embed modulesmod1,mod2,
andpackage.mod3.When youimport a module, MicroPython checks for an embedded/frozen version
of it before looking to the file system.
MicroPython v1.9.4-803-g4b0a8eada-dirty on 2018-06-21; XBC LTE Cat 1 Verizon with
EFM32G
Type "help()" for more information.
>>> import os
>>> os.chdir('lib')
>>> os.bundle('urequests.mpy', 'umqtt/simple.mpy')
bundling urequests.mpy...2196 bytes of raw code
bundling umqtt/simple.mpy...2916 bytes of raw code
Used 72/371 QSTR entries.
stack: 844 out of 3584
GC: total: 32000, used: 12288, free: 19712
No. of 1-blocks: 114, 2-blocks: 77, max blk sz: 45, max free sz: 775
Embedded 2 module(s) to 5851/31152 bytes of flash.
soft reboot
MicroPython v1.9.4-803-g4b0a8eada-dirty on 2018-06-21; XBC LTE Cat 1 Verizon with
EFM32G
Type "help()" for more information.
>>> import os
>>> os.bundle()
['urequests', 'umqtt/simple']
>>> import urequests
>>> import umqtt.simple
Digi modified slicing for bytes and strings operations
Upstream MicroPython only allows bytes and string objects to be sliced with a step size of one. Digi
has modified these types to allow standard slicing syntax with other values, including negative.
Digi MicroPython Programming Guide
39
Page 40
Power management in MicroPython
Prevent sleep from MicroPython41
Initiate sleep from MicroPython42
Sleeping with AT commands43
Idle a device from MicroPython43
Digi MicroPython Programming Guide
40
Page 41
Power management in MicroPythonPrevent sleep from MicroPython
Prevent sleep from MicroPython
Note This section only applies to devices that support the Power Management feature.
When the XBee device enters sleep mode, any MicroPython code currently executing is suspended
until the device comes out of sleep. When the XBee device comes out of sleep mode, MicroPython
execution continues where it left off.
If you use SM sleep, MicroPython can use XBee().wake_lock to force the device to stay awake during
critical operations, for example, when the device is configured for one of the ATSM sleep options
(excluding SM = 6 MicroPython Sleep). The following example shows how to use the XBee().wake_
lock:
Note wake_lock is a context manager. See Context Manager Documentation for more instructions on
usage.
import xbee
xb = xbee.XBee()
# do things interruptable by sleep
with xb.wake_lock:
# do important things
# back to things that are safe to interrupt
XBee Cellular Modem:
Upon entering sleep mode, the XBee Cellular Modem closes any active TCP/UDP connections and
turns off the cellular component. As a result, any sockets that were opened in MicroPython prior to
sleep report as no longer being connected. This behavior appears the same as a typical socket
disconnection event.
The following is a summary of the behavior to expect from the main socket methods:
n socket.send raises OSError: ENOTCONN
n socket.recv returns an empty string, the traditional end-of-file return value
Note As of the x09 firmware, all time-related APIs include the time spent in sleep. Prior firmware
versions paused the millisecond timer used by time.sleep(), time.sleep_ms() and time.time(), so
having a 15-second SM (Sleep Mode)-triggered sleep occur during a MicroPython time.sleep(30)
would result in a 45 second delay in execution. With the x09 firmware, it only delays for 30 seconds.
Upon entering sleep mode the device shuts down all peripheral resources for the lowest possible
current consumption, then upon device wake the peripheral resources are restored and the device
continues with MicroPython code execution.
Digi MicroPython Programming Guide
41
Page 42
Power management in MicroPythonInitiate sleep from MicroPython
Initiate sleep from MicroPython
Note This section only applies to devices that support the Power Management feature.
XBee Cellular Modem:
If you disable sleep modes by setting SM (Sleep Mode) to 0, you can use XBee().sleep_now() and
XBee().wake_reason() to control when the module sleeps. When selecting sleep and wake times on
the XBee Cellular Modem, take into consideration the time it takes to close network connections and
shut down the cellular connection before sleeping, and then to restore the connection when waking
back up.
When setting SM (Sleep Mode) to 6, you can use XBee().sleep_now() and XBee().wake_reason() to
control when the device sleeps. The device sleeps for the time period programmed with an optional
early pin wake (DTR, commissioning button, or SPI_SSEL).
sleep_now(timeout_ms, pin_wake=False)
Sleeps for timeout_ms milliseconds and then wakes.
n If pin_wake is set to True, the device will wake before timeout_ms if DIO8 transitions from
high to low—that is on a falling edge of the line.
n If timeout_ms is None then pin_wake must be set to True and the device will sleep
indefinitely until a falling edge on DIO8 occurs.
n If a timeout is specified—timeout_ms is not None—the function will return the actual elapsed
time in milliseconds after the device wakes.
n Throws an EALREADY OSError exception if SM is not configured correctly for MicroPython to
control sleep.
Note The sleep time reported includes code execution overhead—several milliseconds.
wake_reason()
Returns either xbee.RTC_WAKE if the full timeout_ms elapsed, or xbee.PIN_WAKE when enabled
and DIO8 woke the device early.
The following example shows power management with MicroPython:
from machine import Pin
import time
import xbee
def read_switch(iopin = None):
if iopin.value() == 0:
print("SW2 has been pressed!")
return True
return False
# Configure DIO0(SW2) to put module to sleep
Digi MicroPython Programming Guide
42
Page 43
Power management in MicroPythonSleeping with AT commands
dio0 = Pin('D0', Pin.IN, Pin.PULL_UP)
x = xbee.XBee()
print("\n")
print("How to use this example:")
# pressing SW2 triggers sleep for 30 seconds
print("Option 1 press SW2 and let the program run until it wakes from 30
seconds sleep.")
print("Option 2 press SW2 to put the module under sleep for 30 seconds, "
"then while its sleeping toggle DTR by Close/Open MicroPython Terminal
Com port.")
print("Option 3 press SW2 then do ^C (cancel) to exit example program while
its sleeping")
print("Waiting for SW2 to be pressed to Sleep. Please Press SW2")
while True:
sw2 = read_switch(dio0)
if sw2:
# sleep for 30 seconds, wake early DTR toggled active.
print("sleeping for 30 seconds")
sleep_ms = x.sleep_now(30000, True)
print("slept for %u ms" % sleep_ms)
if x.wake_reason() is xbee.PIN_WAKE:
print("woke early on DTR toggle")
Sleeping with AT commands
Even on devices that do not support the Power Management feature, sleep can be controlled normally
using the SM AT command while MicroPython code is running. When the XBee device enters deep
sleep mode, any MicroPython code currently executing is suspended until the device comes out of
sleep. When the XBee device comes out of sleep mode, MicroPython execution continues where it left
off.
Idle a device from MicroPython
Note This section only applies to the XBee 3 Zigbee RF Module, XBee 3 802.15.4 RF Module, and XBee
3 DigiMesh RF Modules. See Which features apply to my device? for a list of the supported features.
Normally, an XBee device acting as a sleeping end device can receive data any time it is awake. If a
MicroPython application needs the device to be awake but does not need to receive RF transmissions,
the application can put the XBee device into an idle state. When the device is in the idle state, current
draw is reduced and the device will not receive any RF transmissions.
Note This only affects the device's primary RF interface—if Bluetooth is enabled, the device will still be
able to communicate over Bluetooth and the current reduction will be less.
Enter and exit the idle state
Use the xbee.idle_radio() function to put the device into a forced idle state. xbee.idle_now(true)
puts the device into this state, and xbee.idle_now(false) returns it to normal operation.
Digi MicroPython Programming Guide
43
Page 44
Power management in MicroPythonIdle a device from MicroPython
Transmit from an idle device
While the device is idle, xbee.transmit() can be used to send packets just like in normal operation.
The device will be enabled just long enough to complete the transmission, then return to the idle
state.
Send data to an idling device
Because a device that uses the idle_radio() feature is not always able to receive transmissions, you
must take care if data needs to be sent to an idling device. Functionally, sending data to an idling
device is equivalent to sending data to a sleeping device. See the sections on sleep and indirect
messaging in the user guide for the protocol you use for more information on how to transmit to a
sleeping device.
Poll for data while the device is idle
This section only applies to the XBee 3 Zigbee RF Module. See Which features apply to my device? for a
list of the supported features.
The Zigbee protocol uses a polling system to deliver messages to sleeping—or idling—end devices.
Messages for a sleeping end device are stored on a nearby router—the "parent"—and the sleeping
end device periodically queries the router to see if any messages are available. When the device is
idled, this querying must be triggered by the MicroPython application instead of occuring
automatically.
In order to receive data while the device is idled, the MicroPython application must periodically call
xbee.poll_now() to check for incoming data. Calling poll_now() causes the device to check for
messages stored by its parent, and will retrieve a single message from the parent if any are available.
xbee.poll_now() does not return the retrieved packet—the packet is instead passed to MicroPython
via the normal method, either by the application calling xbee.receive() or through a callback if one is
registered.
Note xbee.poll_now() is a non-blocking call, meaning it will return before the polling is complete. It
can take approximately 10 ms after calling poll_now() before a message is available to xbee.receive
().
We recommend registering a callback for received packets when using xbee.poll_now(). That way,
once the packet is retrieved from the parent it is immediately handled by the application.
Since xbee.poll_now() only retrieves a single packet from the parent, it may need to be called more
than once if more than one message may be received between polls. One way to do so is by calling
xbee.poll_now() again every time a packet is received, or in the receive callback.
Configure the parent
You must configure two parameters on the network—including non-sleeping devices—in order for
messages to be delivered correctly on the network.
n SP determines how long the parent will hold on to messages for a sleeping device. The parent
will hold on to messages for three times the value of SP. If the end device always calls poll_now() more frequently than this, no data will be dropped.
n ET must be set to at least the longest time the sleeping device will go between calls to poll_
now(). This value is used as a network timeout; if the end device goes longer than this without
polling, it is considered to have left the network and will need to rejoin the next time it polls.
Digi MicroPython Programming Guide
44
Page 45
Power management in MicroPythonIdle a device from MicroPython
Example
The following code shows some basic usage examples of the idle_radio and poll_now functions. A
more detailed sample application can be found in the xbee-micropython github repository.
import xbee
import time
# Idle the radio
xbee.idle_radio(True)
# Define a callback for received packets
def rx_callback(packet):
print(packet)
xbee.poll_now()
xbee.receive_callback(rx_callback)
# Send a transmission with the radio idled
xbee.transmit(xbee.ADDR_COORDINATOR, "payload", tx_options=1)
# With the radio idled, we have to call poll_now() occasionally or risk
dropping data
while True:
# Application code, etc. can go here
time.sleep(1)
# Check for new messages
xbee.poll_now()
# rx_callback() will be called if the poll comes back with a message
Digi MicroPython Programming Guide
45
Page 46
Access the primary UART
How to use the primary UART47
Example: read bytes from the UART47
Example: read the first 15 bytes from the UART48
Digi MicroPython Programming Guide
46
Page 47
Access the primary UARTHow to use the primary UART
How to use the primary UART
MicroPython provides access to the primary UART via sys.stdin (see sys.stdin limitations) and
sys.stdout (and sys.stderr as an alias to sys.stdout). Unlike Python3, MicroPython does not allowoverriding stdin, stdout and stderr with other stream objects.
sys.stdin sys.stdin supports standard stream methods read and readline in text mode, convertingcarriage return (\r) to newline (\n).
Note Do not use the stdin methods readlines or readinto because they will be removed in future
firmware.
Use sys.stdin.buffer (instead of sys.stdin) for binary mode without any line ending conversions. The
read() method takes a single, optional parameter of the number of bytes to read. For a positive value,
read() blocks until receiving that many bytes from the standard stream methods primary UART. For
non-blocking, call read() without the parameter (or with a negative value) and it returns whatever
characters are available or None if no bytes are waiting.
sys.stdout supports the write() method in text mode, sending an additional carriage return (\r)
before each newline (\n). Use sys.stdout.buffer (instead of sys.stdout) for binary mode without any
line ending conversions. The write() method buffers its output, and can return before sending all bytes
out on the UART.
sys.stdin limitations
Note that sys.stdin provides access to a filtered input stream with the following limitations:
n Only works as long as ATAP = 4.
n You can only configure the primary serial port via AT commands (for example ATBD to set the
baud rate) and not from MicroPython.
n Receiving a Ctrl-C character generates a KeyboardInterrupt.
l You can change the interrupt character using micropython.kbd_intr(ch) where ch is the
new character to use (3 corresponds to Ctrl-C) or -1 to disable the keyboard interrupt
entirely.
l MicroPython always resets the keyboard interrupt to Ctrl-C at the start of each REPL line,
before executing code entered via paste mode, and when executing compiled code at
startup or via Ctrl-R.
n The escape sequence (configured with ATCC, +++ by default) protected by a guard time
(configured with ATGT, 1 second by default) of no data before and after the escape sequence
will always enter Command mode.
l Escape sequence handling can cause delays when reading from sys.stdin.
l You can send ATPY^ in Command mode to force a KeyboardInterrupt, even if it was
disabled via micropython.kbd_intr(-1).
Example: read bytes from the UART
The following example reads bytes from the UART and prints it out one at a time until a keyboard
interrupt occurs when you press Ctrl+C.
from sys import stdin, stdout
Digi MicroPython Programming Guide
47
Page 48
Access the primary UARTExample: read the first 15 bytes from the UART
while True:
data = stdin.buffer.read(1)
Example: read the first 15 bytes from the UART
The following example reads the first 15 bytes from the UART and prints it out one at a time. Notice
that keyboard interrupts are disabled.
Ctrl+A: Enter raw REPLmode50
Ctrl+B: Print the MicroPython banner50
Ctrl+C: Regain control of the terminal52
Ctrl+D: Reboot the MicroPython REPL52
Ctrl+E: Enter paste mode53
Ctrl+F: Upload code to flash54
Flash memory and automatic code execution56
Perform a soft-reset or reboot59
Digi MicroPython Programming Guide
49
Page 50
REPL (Read-Evaluate-Print Loop) examplesCtrl+A: Enter raw REPLmode
Ctrl+A: Enter raw REPLmode
Use this command to enter raw REPL mode, which enables you to execute pasted code. This acts like
a paste mode, but the characters are not echoed back.
This command is used for machine-to-machine communication.
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
1. Access the MicroPython environment.
2. Copy the code you want to paste into the XBee device. For example:
print("Hello world")
3. Press Ctrl+A to enter raw REPL mode.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
raw REPL; Ctrl-B to exit
>
4. Right-click at the MicroPython > prompt and select the Paste option.
5. Press Ctrl+D to save the paste action. An "OK" confirmation and the pasted code displays in
the line. The code is saved to the XBee device and immediately executed.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> raw REPL; Ctrl-B to exit
>OKHello world
>
6. Press Ctrl+B to exit raw REPL mode.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> raw REPL; Ctrl-B to exit
>OKHello world
>
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
Ctrl+B: Print the MicroPython banner
Use this command to perform one of the following:
n If MicroPython is in raw REPL mode, press Ctrl+B to return to the regular REPL and print the
MicroPython banner.
n If MicroPython is in the regular REPL mode, press Ctrl+Bto print the banner.
The banner displays the MicroPython version you are using and the build date for that version.
Pressing Ctrl+B does not reboot the REPL. If you need start a fresh REPL session, use the Ctrl+D:
Reboot the MicroPython REPLcommand to reboot the REPL.
Digi MicroPython Programming Guide
50
Page 51
REPL (Read-Evaluate-Print Loop) examplesCtrl+B: Print the MicroPython banner
Print the banner
This example shows how to print the banner.
1. Access the MicroPython environment.
2. Press Ctrl+B to print the banner.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
Print the banner and verify that the memory was not wiped
In this example, a variable "a" is assigned the value "test". When you press Ctrl+B, the banner is
printed.
You can verify that the memory was not wiped by entering the variable "a" and seeing that the value
"test" is the output.
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, type a = "test", then press Enter. This statement assigns the
value "test" to the variable "a".
3. At the MicroPython >>> prompt, type a, then press Enter. The value assigned to the variable
displays.
4. Press Ctrl+B to print the banner.
5. At the MicroPython >>> prompt, type a and press Enter. The assigned value for the variable is
returned.
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
Digi MicroPython Programming Guide
51
Page 52
REPL (Read-Evaluate-Print Loop) examplesCtrl+C: Regain control of the terminal
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> a = "test"
>>> a
'test'
>>> <Ctrl-B>
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> a
'test'
>>>
Ctrl+C: Regain control of the terminal
Use this command to interrupt the currently running program and regain control of the terminal. This
is useful if running the code is taking longer than expected, such as if the code has an incorrectly
coded never-ending loop.
In this example the code has an infinite loop. The code stops the code execution.
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
1. Access the MicroPython environment.
2. Copy the code you want to paste. This example uses the following code:
while True:
pass# This statement means "do nothing"
3. At the MicroPython >>> prompt, type Ctrl+E to enter paste mode. The terminal displays paste
mode; Ctrl-C to cancel, Ctrl-D to finish.
4. At the MicroPython >>> prompt, right-click and the select the Paste option. The code appears
in the terminal and each line is numbered, followed by ===. For example line 1 starts with 1===.
5. Press Ctrl+D to accept and run the pasted code. The code will run continuously until you cancel
it.
6. Press Ctrl+C to stop the code execution. A KeyboardInterrupt exception message prints to
the screen.
7. A MicroPython >>> prompt displays on a new line.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
1=== while True:
2===pass # This statement means "do nothing"
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt:
>>>
Ctrl+D: Reboot the MicroPython REPL
Use this command to reboot the REPL and clear any variable and function definitions.
Digi MicroPython Programming Guide
52
Page 53
REPL (Read-Evaluate-Print Loop) examplesCtrl+E: Enter paste mode
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, type a = "test", then press Enter. This statement assigns the
value "test" to the variable "a".
3. At the MicroPython >>> prompt, type a, then press Enter. The value assigned to the variable
displays.
4. Press Ctrl+D to reboot the REPL. The phrase "soft reboot" followed by the MicroPython banner
prints.
5. At the MicroPython >>> prompt, type the variable "a" (no quotes) and press Enter. Since the
memory was wiped, the variable is not found and the error NameError: name not defined
prints in the output.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> a = 'test'
>>> a
'test'
>>>
soft reboot
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name not defined
Ctrl+E: Enter paste mode
Use this REPL command to enter paste mode. This enables you to paste a block of code into the
terminal, rather than having to type in lines of code.
Note Paste mode evaluates each line in the pasted code block in order, as if the code had been typed
into the REPL.
Paste one line of code
This example uses the following code to show how to copy one line of code and paste it into the
MicroPython Terminal.
1. Access the MicroPython environment.
2. Copy the code you want to paste. This example uses the following code:
print("Hello world")
3. At the MicroPython >>> prompt type Ctrl+E to enter paste mode. The terminal displays paste
mode; Ctrl-C to cancel, Ctrl-D to finish.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
Digi MicroPython Programming Guide
53
Page 54
REPL (Read-Evaluate-Print Loop) examplesCtrl+F: Upload code to flash
paste mode; Ctrl-C to cancel, Ctrl-D to finish
1===
4. At the MicroPython >>> prompt, right-click and select the Paste option.
5. The code appears in the terminal and each line is numbered, followed by ===. For example line
1 starts with 1===.
6. Press Ctrl+D to complete the paste process and run the pasted code.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
paste mode; Ctrl-C to cancel, Ctrl-D to finish
1=== print("Hello world")
Hello world
Paste a code segment
This example uses the following code to show how to copy one line of code and paste it into the
MicroPython Terminal.
1. Access the MicroPython environment.
2. Copy the code you want to paste. This example uses the following code:
for x in range(10):
print("Current number: %d" % x)
if (x < 9):
print("Next number will be: %d\n" % (x + 1))
else:
print("This is the last number!")
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
3. At the MicroPython >>> prompt type Ctrl+E to enter paste mode. The terminal displays pastemode; Ctrl-C to cancel, Ctrl-D to finish.
4. At the MicroPython >>> prompt, right-click and select the Paste option.
5. The code appears in the terminal and each line is numbered, followed by ===. For example line
1 starts with 1===.
6. Press Ctrl+D to complete the paste process and run the pasted code. In this example, you
should see 10 statements print to the terminal that state the current number, and what the
next number will be. The numbers are from 0 to 9.
Ctrl+F: Upload code to flash
You can use flash mode to paste a block of code into MicroPython and store it to flash memory. You
can run the stored code at any time from the MicroPython prompt by pressing Ctrl+R.
When the code is uploaded to the flash memory, the MicroPython volatile memory (RAM) is cleared of
any previously executed code. The uploaded code is saved on the XBee device. This means that only
the last code saved to the flash memory is available.
You can choose to automatically run the code currently stored in the flash memory when the XBee
device boots up.
Digi MicroPython Programming Guide
54
Page 55
REPL (Read-Evaluate-Print Loop) examplesCtrl+F: Upload code to flash
Load code to flash memory
Use this command to upload code to the flash compile mode.
Any code uploaded in the flash memory can be set to run automatically when the XBee Cellular
Modem boots up. You can also press Ctrl+R to re-run the compiled code at any time.
Note You can copy and paste code from the online version of the Digi MicroPython Programming Guide.
Use caution with the PDF version, as it may not maintain essential indentations.
1. Access the MicroPython environment.
2. Copy the code you want to paste into the XBee device. For example:
print("Hello world")
3. Press Ctrl+F.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
flash compile mode; Ctrl-C to cancel, Ctrl-D to finish
1^^^
4. At the MicroPython 1^^^ prompt, right-click and select the Paste option.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
flash compile mode; Ctrl-C to cancel, Ctrl-D to finish
1^^^ print("Hello world")
5. Press Ctrl+D to finish. The code is compiled and stored in flash memory.
Compiling 123 bytes of code...
Used 0/150 QSTR entries.
Compiled 123 bytes of code to 188/7544 bytes of flash.
Automatically run this code at startup [Y/n]?
Note The compilation report includes the number of used/available QSTR entries. The QSTR pool is
used to store string literals from uploaded code. If a piece of code contains too many string literals,
compilation fails and reports a QSTR pool overflow.
6. You can choose whether to have the code stored in the flash memory automatically run the
next time the XBee device is started. Press Enter to leave the setting unchanged (the default
value shown as uppercase).
o
Y: Press Y to automatically run the code stored in flash memory upon startup. This sets
the PS command to 1. Note that this example only works on startup if you have a
terminal open on that serial port and the AP command is set to 4.
o
N: Press N to ensure that the code stored in flash memory is not run the next time the
XBee device is started. This sets the PS command to 0.
Erase the code stored in flash memory
You can erase the code stored in flash memory using one of the following methods.
Digi MicroPython Programming Guide
55
Page 56
REPL (Read-Evaluate-Print Loop) examplesFlash memory and automatic code execution
Note This example assumes you have code stored to flash memory. For information about how to
store code to flash memory, see Load code to flash memory.
Ctrl+D
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, press Ctrl+F to enter flash mode. Do not enter or paste any
code.
3. At the MicroPython >>> prompt, press Ctrl+D to complete the process. A process message
displays:
Erasing stored code...
4. When the process is complete the MicroPython >>> prompt displays in the terminal.
ATPYDcommand
The ATPYDcommand erases stored code and performs a soft reboot. For instructions, see the
MicroPython commands section in the appropriate user guide.
Flash memory and automatic code execution
Flash memory is referred to as "non-volatile" memory, as it retains whatever is stored in it, even
without any power. This allows code stored in the flash memory to be run when you start up the XBee
device.
The sections below explain how to manage code stored in flash memory.
n Run stored code at start-up to flash LEDs (XBee Cellular Modem only)
n Disable code from running at start up
n Enable code to run at start-up
Run stored code at start-up to flash LEDs
Note This section only applies to the XBee Cellular Modem. See Which features apply to my device? for
a list of the supported features.
If you have stored code to the flash memory, you can choose to automatically run this code when the
XBee device boots up.
1. Access the MicroPython environment.
2. Copy the code you want to paste. This example uses the following code, which automatically
blinks the LED lights on the XBIBboard every two seconds.
from machine import Pin
import time
dio10 = Pin("P0", Pin.OUT, value=0)
while True:
time.sleep(1)
dio10.toggle()# Flash the LED on DIO10 (P0)
Digi MicroPython Programming Guide
56
Page 57
REPL (Read-Evaluate-Print Loop) examplesFlash memory and automatic code execution
3. At the MicroPython >>> prompt, press Crtl+F.
4. At the MicroPython 1^^^ prompt, right-click and select the Paste option.
5. The code appears in the terminal and each line is numbered, followed by ^^^. For example, line
1 starts with 1^^^.
6. Press Ctrl+D to finish.
Compiling 123 bytes of code...
Used 0/150 QSTR entries.
Compiled 123 bytes of code to 188/7544 bytes of flash.
Automatically run this code at startup [Y/n]?
7. Press the Y key to run the code at start-up.
8. You may want to test your code before power cycling the device.
9. Press Ctrl+R to run the code compiled in flash. If it is not working correctly, press Ctrl+C to
interrupt it and upload a new version.
10. Once you are happy with the uploaded code, power down the XBee Cellular Modem.
a. Unplug the USB cable from your computer.
b. Disconnect the power supply from the XBIBboard.
c. Wait until the lights on the XBIB board turn off.
d. Reconnect the power. The three LEDs on the XBIB board automatically start turning ON
and OFF every 2 seconds.
11. Connect the USBcable to your computer.
12. Access the MicroPython environment. A MicroPython prompt does not display, as MicroPython
is running the code to blink the LEDs.
13. The terminal seems unresponsive as the code loop executes. Note the three green LEDs to the
right of the USB-B port on the XBIB development board. These LEDs turn ON then OFF every 2
seconds.
14. At the terminal, press Ctrl+C to stop code execution and regain control of the terminal. A
MicroPython prompt displays and the LEDs stop flashing.
Disable code from running at start up
For code that you saved to the flash memory and specified that the code should run at start up, you
can change your choice and choose not to automatically run the code at start up. You can change your
choice without saving the code to the flash memory again.
1. Use Ctrl+F to save code to the flash memory and choose to run it at start up.
2. At the Serial Console, enter Command mode by sending +++ and receiving an OK response.
3. At the prompt, type ATPS and press Enter. The terminal should echo back 1, since the code in
the flash memory is set to run at start up.
4. At the prompt, type ATPS0 and press Enter. This statement disables automatic code execution
at start up.
5. At the prompt, type ATWR and press Enter. This statement writes the change to the flash
memory.
6. At the prompt, type ATCN and press Enter. This statement exits Command mode.
7. Disconnect the USB cable from your computer.
Digi MicroPython Programming Guide
57
Page 58
REPL (Read-Evaluate-Print Loop) examplesFlash memory and automatic code execution
8. Close the Serial Console.
9. Disconnect the power from the XBIB board.
10. After the LEDs on the XBIB board have all turned off, reconnect the power to the XBIBboard.
11. Connect the USB cable to your computer. Notice that the LEDs do not blink, which verifies that
you have successfully disabled the automatic code execution at start up.
Ctrl+R: Run code in flash
You can use this command to re-run the code in the flash memory.
1. Access the MicroPython environment.
2. Load code to flash memory.
3. Press Ctrl+R to re-run the code in the flash memory.
MicroPython v1.9.3-999-g00000000 on 2018-01-01; XBee Module with EFX32
Type "help()" for more information.
>>>
Running 76 bytes of stored bytecode...
Hello world
Enable code to run at start-up
For code that you saved to the flash memory and chosen not to run at start up, you can change your
choice and enable the code to automatically run at start up. You can change your choice without
saving the code to the flash memory again.
1. For this example, you need code stored in flash memory that will not automatically run at
start-up. Use Ctrl+F to save code to the flash memory. You can either:
n Press N and choose not to run it at start up.
n Press Y to run the code in flash memory at start-up. If you chose Yes, for this example
you should Disable code from running at start up.
Remember that in this example, when MicroPython is not set to automatically run at start-up,
the LEDs do not blink on module start-up.
2. At the Serial Console, enter Command mode by sending +++ and receiving an OK response.
3. At the prompt, type ATPS and press Enter. The terminal should echo back 0, since the code in
the flash memory is not set to run at start-up.
4. At the prompt, type ATPS1 and press Enter. This statement enables automatic code execution
at start up.
5. At the prompt, type ATWR and press Enter. This statement writes the change from the
previous statement to the flash memory.
6. At the prompt, type ATCN and press Enter. This statement exits command mode.
7. Press the Reset button on the XBIBboard.
8. Notice that the LEDs blink ONand OFF, which verifies that you have successfully enabled the
automatic code execution at start up.
Digi MicroPython Programming Guide
58
Page 59
REPL (Read-Evaluate-Print Loop) examplesPerform a soft-reset or reboot
Perform a soft-reset or reboot
If you want to soft-reset the REPL you can press Ctrl+D in the REPL, or run machine.soft_reset() to
force a soft reset from code.
If you want to reboot the entire XBee device, run xbee.atcmd('FR').
Digi MicroPython Programming Guide
59
Page 60
Access file system in MicroPython
Note This section only applies to devices that support the File System feature.
Directory and file names follow the rules in Paths.
Modify file system contents61
Access data in files63
File object methods63
Import modules from file system64
Reload a module65
Compiled MicroPython files65
Digi MicroPython Programming Guide
60
Page 61
Access file system in MicroPythonModify file system contents
Modify file system contents
The uos module contains the following methods to interact with the file system.
uos.chdir(dir)
Change the current working directory.
uos.getcwd()
Get the current working directory.
Note MicroPython maintains a separate working directory from the FS (File System)command
processor.
uos.ilistdir([dir])
This function returns an iterator which then yields tuples corresponding to the entries in the directory
that it is listing. With no argument it lists the current directory, otherwise it lists the directory given by
dir. The tuples have the form (name, type, inode, size):
n name: A string (or bytes if dir is a bytes object) and it is the name of the entry.
n type: An integer that specifies the type of the entry, with 0x4000 for directories and 0x8000 for
regular files.
n inode: An integer corresponding to the inode of the file. On XBee devices, set to 0 for regular
files and directories and -1 for secure files.
n size: An integer representing the size of the file or -1 if unknown. Its meaning is currently
undefined for directory entries.
uos.listdir([dir])
Returns a list of files in the given directory. With no argument it uses the current working directory (.).
uos.mkdir(dir)
Create a new directory.
uos.remove(file)
Remove a file.
uos.rmdir(dir)
Remove a directory. Fails if dir is not empty.
uos.rename(old_path, new_path)
Rename or move a file or directory. Fails if new_path already exists.
Note This function is only available on modules that support renaming files.
Digi MicroPython Programming Guide
61
Page 62
Access file system in MicroPythonModify file system contents
uos.replace(old_path, new_path)
Replace a file or directory (new_path) with another (old_path).
Note This function is only available on modules that support renaming files.
uos.sync()
Sync all file systems.
uos.compile(source_file, mpy_file=None)
This is an XBee extension to uos. Compile Python source code in source_file and store in a file with an
.mpy extension. Default is to remove the .py extension from source_file and append .mpy to
generate mpy_file. See Import modules from file system for details on using .mpy files.
Compilation involves three steps: parsing, compiling and saving to the file system. MicroPython prints
information about heap usage before each step so you can monitor heap requirements for a device,
and consider splitting it into two (or more) modules or compiling with the MicroPython cross compiler
(mpy-cross) on your computer instead of compiling on the XBee device.
>>> uos.compile('urequests.py')
stack: 644 out of 3584
GC: total: 32000, used: 688, free: 31312
No. of 1-blocks: 12, 2-blocks: 7, max blk sz: 8, max free sz: 1716
Parsing urequests.py...
stack: 644 out of 3584
GC: total: 32000, used: 8000, free: 24000
No. of 1-blocks: 20, 2-blocks: 12, max blk sz: 88, max free sz: 1415
Compiling...
stack: 644 out of 3584
GC: total: 32000, used: 3872, free: 28128
No. of 1-blocks: 45, 2-blocks: 35, max blk sz: 42, max free sz: 1254
Saving urequests.mpy...
>>> list(uos.ilistdir())
[('urequests.py', 32768, 0, 3407), ('urequests.mpy', 32768, 0, 2657)]
uos.format()
This is an XBee extension to uos. Reformats the SPI flash and creates the default directory structure.
uos.hash([secure_file])
This is an XBee extension to uos. Returns a 32-byte bytes object with the sha256 hash digest of a
secure file. You can use this value to verify that a secure file matches an unencrypted copy of the file.
See FS HASH filename for more information on using this digest. If secure_file is not specified, it
returns a string identifying the hash method (sha256). You can convert the 32-byte digest to a 64character hexdigest with the following code snippet:
The built-in method open() is an alias to uio.open(file, mode='r') which returns a file object—an
uio.FileIO object for binary modes and an uio.TextIOWrapper object for text modes. If the file cannot
be opened, an OSError is raised.
Parameter file is a path-like object giving the path—absolute or relative to the current working
directory—of the file to be opened.
Parameter mode is an optional string that specifies the mode in which the file is opened. It defaults to
'r' which means open for reading in text mode. Other common values are 'w' for writing (truncating
the file if it already exists), 'x' for exclusive creation and 'a' for appending—all writes append to the
end of the file regardless of the current seek position. The available modes are:
CharacterMeaning
'r'Open for reading (default).
'w'Open for writing, truncating file file. On modules that do not support editing files after
creation, this will fail if the file already exists.
'x'Open for exclusive creation, failing if the file already exists.
'a'Open for writing, always appending to the end of the file. Only available on modules
that support editing files after creation.
'b'Binary mode.
't'Text mode (default).
'+'Open a disk file for updating (reading and writing). Only available on modules that
support editing files after creation.
'*'(XBee extension) open a secure file for writing. Only available on modules that support
secure files.
The default mode is 'r'—open for reading text, a synonym of 'rt'. For binary read-write access, the
mode 'w+b' opens and truncates the file to 0 bytes. 'r+b' opens the file without truncation.
Python distinguishes between binary and text I/O. Files opened in binary mode—including 'b' in the
mode argument—return contents as bytes objects without any decoding. In text mode—the default,
or when 't' is included in the mode argument—the contents of the file are returned as str.
File object methods
The following methods interact with file objects.
read(size=-1)
Read up to size bytes from the object and return them. As a convenience, if size is unspecified or -1, all
bytes until end-of-file (EOF) are returned.
Digi MicroPython Programming Guide
63
Page 64
Access file system in MicroPythonImport modules from file system
readinto(b)
Read bytes into a pre-allocated, writable bytes-like object b, and return the number of bytes read.
readline(size=-1)
Read and return one line from the stream. If size is specified, at most size bytes are read.
readlines()
Read and return a list of lines from the stream. MicroPython does not support Python3's hint
parameter.
Note It is already possible to iterate on file objects using for line in file: ... without calling
file.readlines().
write(b)
Write the given bytes-like object, b, to the underlying raw stream, and return the number of bytes
written.
seek(offset, whence=0)
Note Seeking is disabled when writing to secure files.
Change the stream position to the given byte offset. offset is interpreted relative to the position
indicated by whence. The default value for whence is 0 (SEEK_SET). Values for whence are:
n 0 (SEEK_SET) – start of the stream (the default); offset should be zero or positive
n 1 (SEEK_CUR) – current stream position; offset may be negative
n 2 (SEEK_END) – end of the stream; offset is usually negative
Returns the new absolute stream position.
tell()
Return the current stream position.
flush()
Flush the write buffers of the stream if applicable. This does nothing for read-only streams.
close()
Flush and close the stream. This does nothing if the file is already closed.
Import modules from file system
Python code can access code in modules using the builtin import command. When executing the line
import foo, MicroPython goes through each entry in sys.path looking for a module called foo. It firstchecks for a package by looking for the file __init__.py in the directory foo. It then checks for a file
foo.py and finally foo.mpy (a pre-compiled Python file) before moving to the next entry in sys.path.
Digi MicroPython Programming Guide
64
Page 65
Access file system in MicroPythonReload a module
On startup, the XBee device sets its sys.path to a default of ['', '/flash', '/flash/lib'].
Reload a module
If you want to reload a module after uploading a revised source file, use the following method to
discard the old module and re-import from the updated file.
Note This is also necessary if the previous import attempt failed due to a syntax error.
import sys
def reload(mod):
mod_name = mod.__name__
del sys.modules[mod_name]
return __import__(mod_name)
Compiled MicroPython files
With the file system, the XBee device supports compiled MicroPython code in the form of .mpy files.
You can convert a .py file to a .mpy file on the XBee device using the uos.compile() method; see
Modify file system contents. The XBee device also supports .mpy files created with mpy-cross, the
MicroPython cross-compiler. You can download mpy-cross for Windows, Linux and MacOS from the
mpy-cross project.
Note You should pass -mno-unicode and -msmall-int-bits=31 to mpy-cross when cross-compiling for
the XBee device.
The benefit of using a .mpy file is that MicroPython can load it to the heap with minimal overhead,
unlike the parsing and compiling process which could require a 32 kB heap to create a 7 kB .mpy file.
Since MicroPython checks for .py files in a given directory before .mpy files, you need to organize your
files so the .mpy comes up first during an import search. One technique is to keep the Python source
in lib/source/ and then compile to an .mpy file in lib/ after uploading new files; for example, with
/flash/lib as the current working directory, uos.compile('source/foo.py', 'foo.mpy').
Digi MicroPython Programming Guide
65
Page 66
Send and receive User Data Relay frames
Note This section applies to the XBee Cellular Modem and the XBee 3 Zigbee RF Module. See Which
features apply to my device? for a list of the supported features.
You can send and receive User Data Relay Frames from MicroPython using the relay module from thexbee module. Import the module with the statement: from xbee import relay
Constants67
Methods67
Examples68
Digi MicroPython Programming Guide
66
Page 67
Send and receive User Data Relay framesConstants
Constants
Interfaces (always defined)
relay.SERIAL: 0
relay.BLUETOOTH: 1
relay.MICROPYTHON: 2
Limits
relay.MAX_DATA_LENGTH: maximum length of data passed to relay.send()
Methods
relay.receive()
Returns None if a frame is not available, otherwise a dictionary with entries for the sender (one of the
interfaces, for example, relay.SERIAL), and message (a bytes object).
relay.send(dest, data)
Pass one of relay.SERIAL, relay.BLUETOOTH or relay.MICROPYTHON (for loopback) as dest. Can use
sender from the dictionary returned from receive() as dest parameter. The data parameter should
be a bytes or string object, or any other object that implements the buffer protocol. You can send a
maximum of relay.MAX_DATA_LENGTH bytes in a single frame.
Exceptions
The send() method throws exceptions in at least the following cases:
n ValueError or TypeError for invalid parameters.
n OSError(ENOBUFS) if unable to allocate a buffer for the frame.
n OSError(ENODEV) for invalid dest parameter.
n OSError(ECONNREFUSED) when destination is not accepting frames (for example, the serial
interface is not in API mode, Bluetooth is not connected and unlocked, the queue is full or
delivery failed).
relay.callback(my_callback)
Note This section only applies to the XBee 3 Cellular Modem firmware x15 or later. See Which features
apply to my device? for a list of the supported features.
Register a callback that will be called whenever a user data relay frame is received.
The callback function must take one parameter:
Digi MicroPython Programming Guide
67
Page 68
Send and receive User Data Relay framesExamples
n A dictionary with the following keys:
l message: The received data in bytearray format.
l sender: The source interface.
Note When a callback is registered, using relay.callback() will raise an error as only one method of
relay frame delivery is supported at a time.
Examples
Digi has provided example applications which demonstrate how to use User Data Relay frames from
MicroPython.
You can read these examples on GitHub: https://github.com/digidotcom/xbee-
If you use the Digi XBee MicroPython PyCharm Plugin you can load the examples using File> ImportXBee MicroPython Sample Project... in the XBEE / COMMUNICATION folder.
Digi MicroPython Programming Guide
68
Page 69
MicroPython libraries on GitHub
Note This section only applies to the XBee Cellular Modem. See Which features apply to my device? for
a list of the supported features.
On GitHub, we maintain modules and sample code for use on XBee devices with MicroPython. The
code is available atgithub.com/digidotcom/xbee-micropython. The samples include:
n Secure Sockets Layer (SSL)and Transport Layer Security (TLS). See The ussl module.
n Amazon Web Services (AWS). These samples demonstrate how to connect to AWS IoT and
publish and subscribe to topics using the umqtt.simple module. See Use AWS IoT from
MicroPython.
n File Transfer Protocol (FTP). Micro File Transfer Protocol client.
n MQ Telemetry Transport (MQTT). MQTT client for publish/subscribe. See Publish to a topic.
n Digi Remote Manager. An HTTP client for Digi Remote Manager.
Digi MicroPython Programming Guide
69
Page 70
MicroPython modules
You can use many MicroPython modules with the XBee device. You can obtain a list of the available
modules and of the module properties from the REPL. For more information see Discover available
modules.
XBee-specific functions71
Standard modules and functions71
Discover available modules72
Digi MicroPython Programming Guide
70
Page 71
MicroPython modulesXBee-specific functions
XBee-specific functions
The following functions are specifically for use with the XBee device.
n Machine module
n Cellular network configuration module
n XBee module
n digi.cloud module
Standard modules and functions
The table below describes the MicroPython modules that you can use with the XBee device. For some
functions and classes, you can only use a subset of the functions and classes with the XBee device. The
table specifies those that you can use.
For a complete description of the MicroPython libraries and the related functions, see MicroPython
libraries.
Note The MicroPython modules starting with "u" have aliases to the standard Python module names.
FunctionDescription
MicroPython
Functions used to access and control MicroPython internals.
functions
Note The standard set of MicroPython functions work with the XBee device.
Builtin
Basic functions built in to MicroPython.
Functions
gc
Functions that control the garbage collector.
sysSystem-specific functions.
n sys.print_exception(exc, file=sys.stdout)
Available constants:
n sys.argv
n sys.byteorder
n sys.implementation
n sys.maxsize
n sys.modules
n sys.path
n sys.platform
n sys.version
n sys.version_info
ubinascii
This module implements conversions between binary data and various encodings of
it in ASCII form (in both directions).
Digi MicroPython Programming Guide
71
Page 72
MicroPython modulesDiscover available modules
FunctionDescription
ucryptolib
uhashlib
uio
ujson
uselectThis module provides functions to efficiently wait for events on multiple streams
usocket(XBee Cellular Modem only) This module provides access to the BSD socket
ustruct
utimeXBee Cellular Modem: This module provides functions for getting the current time
This module provides an Advanced Encryption Standard (AES) API in MicroPython to
perform encryption and decryption of data or files.
This module implements binary data hashing algorithms.
This module contains additional types of stream (file-like) objects and helper
functions.
This module performs JSON encoding and decoding.
(select streams which are ready for operations)
This is currently only available on the XBee Cellular Modem with firmware x15 and
later as it primarily applies to sockets.
interface.
See Sockets for samples of using sockets with the XBee Cellular Modem.
This module provides functions to pack and unpack primitive data types.
and date, measuring time intervals, and for delays.
XBee 3 Zigbee RF Module: This module provides functions for measuring time
intervals, and for delays.
Discover available modules
You can obtain a list of the available modules and of the module properties from the REPL.
Note The MicroPython modules starting with "u" have aliases to the standard Python module names.
1. Access the MicroPython environment.
2. At the MicroPython >>> prompt, type help('modules') and press Enter. A list of available
modules displays.
3. You can display a list of a module's properties and methods. In these steps, (modulename) in
the command should be replaced by the module you are interested in.
a. At the MicroPython >>> prompt, type import modulename, and press Enter.
b. At the MicroPython >>> prompt, type help(modulename) and press Enter. A list of the
module's properties and methods displays.
Digi MicroPython Programming Guide
72
Page 73
Machine module
The machine module contains specific functions related to the XBee device.
For a detailed description of the MicroPython machine functions, see the machine function section in
the standard MicroPython documentation.
Reset-cause74
Random numbers74
Unique identifier74
Class PWM (pulse width modulation)74
Class ADC: analog to digital conversion75
Class I2C: two-wire serial protocol77
Class Pin82
Class UART82
Class WDT: watchdog timer85
Access the XBee device's I/O pins85
Use the Pin() constructor87
Use mode() to configure a pin87
Use pull() to configure an internal pull up/down resistor89
Digi MicroPython Programming Guide
73
Page 74
Machine moduleReset-cause
Reset-cause
This function returns the cause of a reset. See Reset-cause for possible return values.
machine.reset_cause()
Constants
These return values describe the cause of a reset.
machine.BROWNOUT_RESET
machine.LOCKUP_RESET
machine.PWRON_RESET
machine.HARD_RESET
machine.WDT_RESET
machine.DEEPSLEEP_RESET
machine.SOFT_RESET
Random numbers
The machine.rng() method returns a 30-bit random number that is generated by the software.
The uos.urandom(n) method returns a bytes object with n random bytes generated by the hardware
random number generator.
Unique identifier
The machine.unique_id() function returns a 64-bit bytes object with a unique identifier for the
processor on the XBee Cellular Modem.
In some MicroPython ports, the ID corresponds to the network MAC address.
Class PWM (pulse width modulation)
Note This section only applies to devices that support the Pin I/O feature.
This class is not supported on the XBee Cellular Modem.
You use this function to enable PWM on XBee devices using pin P0.
The duty cycle is between 0 and 1023, inclusive of the end points. PWM cannot read or write the
frequency.
This function uses the machine.PWM class. For information about the MicroPython machine module,
see machine — functions related to the hardware.
For XBee devices that support PWM1, change the instances of P0 to P1 in the example program.
Digi MicroPython Programming Guide
74
Page 75
Machine moduleClass ADC: analog to digital conversion
from machine import Pin, PWM
pwm0 = PWM(Pin('P0'))# create PWM object from a pin
pwm0.duty()# get current duty cycle
pwm0.duty(200)# set duty cycle
pwm0.deinit()# turn off PWM on the pin
pwm0 = PWM('P0', duty=512) # create and configure in one go
The following REPLsession makes use of the PWMclass:
>>> from machine import PWM
>>> pwm0 = PWM('P0')
>>> pwm0.freq()# report the frequency (23.46kHz)
23460
>>> pwm0.freq(10000) # can't change fixed frequency on XBee
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NotImplementedError: can't set PWM frequency
>>> pwm0.duty()# report the duty cycle
0
>>> pwm0.duty(255)# set 25% duty cycle
>>> pwm0.duty(511)# set 50% duty cycle
>>> pwm0.duty(767)# set 75% duty cycle
>>> pwm0.duty(1023)# set 100% duty cycle
>>> pwm0.duty()# report the duty cycle
1023
>>> pwm0.deinit()# disable DIO10
Note Supported on XBee 3 cellular only. Not supported on XBee Cellular Cat 1 Verizon and XBee
Cellular 3G.
Class ADC: analog to digital conversion
Note This section only applies to devices that support the Pin I/O feature.
Use this class to read analog values on a pin.
import machine
apin = machine.ADC('D0')# create an analog pin on D0
val = apin.read()# read an analog value
print(val)# display analog value
Constructors
You can create an ADC object associated with the assigned pin. You can then read analog values on
that pin.
class machine.ADC('D0')
Note For the XBee Cellular Modem the ADC analog reference is 2.5 V and the pin input range is 0 - 2.5
V. The ADC reference voltage and input range for XBee 3 Zigbee, DigiMesh and 802.15.4 are based on
the AV value which can be 0 = 1.25 V, 1 = 2.5 V or 2 = VDD.
Digi MicroPython Programming Guide
75
Page 76
Machine moduleClass ADC: analog to digital conversion
Note The ADC reading value has a resolution of 12 bits with a range of 0 - 4095.
Methods
Read the analog value
This function allows you to read the ADC value.
apin.read()
Note apin.read() returns a raw ADC sample. Use the following equation to convert this value to mV:
sample mV = (A/D reading * Vref mV) / 4095
Read the analog value as a 16-bit number
This function allows you to read the ADC value and get the result as a 16-bit number—0 to 65535. This
function is provided for compatibility with other MicroPython implementations.
XBee devices only support 12-bit ADC readings. Readings from read_u16() will match those from read
(), scaled to a 16-bit range.
apin.read_u16()
Note apin.read_u16() returns a raw ADC sample. Use the following equation to convert this value to
mV:
sample mV = (A/D reading * Vref mV) / 65535
Note This function is available on XBee Cellular and XBee 3 Cellular products with firmware ending in
*16 or newer, and XBee 3 DigiMesh, 802.15.4 and Zigbee devices with firmware ending in *0B or
newer.
Sample program
The following sample program applies to the XBee 3 Zigbee, DigiMesh, and 802.15.4.
import machine
import xbee
x = xbee.XBee()
print('Setting the analog reference to 1 (2500 mV)')
x.atcmd('AV', 1)
print('Analog reference set to %d' % x.atcmd('AV'))
# Take an analog measurement
apin = machine.ADC('D0')
raw_val = apin.read()
val_mv = (raw_val * 2500)/4095
print('Measured %d mV' % val_mv)
Digi MicroPython Programming Guide
76
Page 77
Machine moduleClass I2C: two-wire serial protocol
Class I2C: two-wire serial protocol
Note This section only applies to devices that support the I2C feature.
I2C is a two-wire protocol for communicating between devices. At the physical level it consists of two
wires: SCL and SDA, the clock and data lines respectively.
When created, I2C objects are associated with a specific two wire bus. They can be initialized when
created, or initialized later on.
Printing the I2C object gives you information about its configuration.
The XBee device can function as an I2C master controlled by MicroPython. This allows you to perform
basic sensing and actuation with I2C devices such as sensors and actuators via MicroPython without
an additional microcontroller.
The MicroPython API is the same as documented in the MicroPython library reference except that the
XBee device does not support primitive operations or the deinit operation.
The I2C implementation is provided through hardware, so when you use machine.I2C to initialize I2C,
use the id parameter to select the interface. The only valid value is 1, which uses DIO1 for SCL and
DIO11 for SDA. Using the scl and sda parameters to select pins is not valid on the XBee device.
Note You are not required to configure the XBee I/O using AT commands prior to creating an I2C
object. The appropriate I/O configuration will be performed automatically.
The following table shows the pin layout associated with the example below.
PinAT commandSMTpinMMT pinTH pin
I2C SCL(DIO1)
I2C SDA (DIO11)
D1
P1
323019
887
An example of using I2C follows:
from machine import I2C
i2c = I2C(1, freq=400000)# create I2C peripheral at frequency of
400kHz
i2c.scan()# scan for slaves, returning a list of 7bitaddresses
i2c.writeto(42, b'123')# write 3 bytes to slave with 7-bit address
42
i2c.readfrom(42, 4)# read 4 bytes from slave with 7-bit address
42
i2c.readfrom_mem(42, 8, 3)# read 3 bytes from memory of slave 42,
#starting at memory-address 8 in the
slave
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of slave 42
#starting at address 2 in the slave
Constructors
class machine.I2C(id, *, freq=400000)
Digi MicroPython Programming Guide
77
Page 78
Machine moduleClass I2C: two-wire serial protocol
Construct and return a new I2C object using the following parameters:
n id identifies a particular I2C peripheral. This version of MicroPython supports a single
peripheral with id 1 using DIO1 for SCL and DIO11 for SDA.
n freq should be an integer that sets the maximum frequency for SCL.
General methods
I2C.scan()
Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of addresses of slave devices
that respond. A device responds if it pulls the SDA line low after its address (including a write bit) is
sent on the bus.
Standard bus operations methods
The following methods implement the standard I2C master read and write operations that target a
given slave device.
I2C.readfrom(addr, nbytes, stop=True)
Read nbytes from the slave specified by addr. If stop is true then a STOP condition is generated at
the end of the transfer. Returns a bytes object with the data read.
I2C.readfrom_into(addr, buf, stop=True)
Read into buf from the slave specified by addr. The number of bytes read will be the length of buf. If
stop is true then a STOP condition is generated at the end of the transfer.
The method returns None.
I2C.writeto(addr, buf, stop=True)
Write the bytes from buf to the slave specified by addr. If a NACK is received following the write of a
byte from buf then the remaining bytes are not sent. If stop is true then a STOP condition is
generated at the end of the transfer, even if a NACK is received. The function returns the number of
ACKs that were received.
Note buf should be a bytearray type object.
Memory operations methods
Some I2C devices act as a memory device (or set of registers) that can be read from and written to. In
this case there are two addresses associated with an I2C transaction: the slave address and the
memory address. The following methods are convenience functions to communicate with such
devices.
Read nbytes from the slave specified by addr starting from the memory address specified by
memaddr. The argument addrsize specifies the address size in bits. Returns a bytes object with the
Read into buf from the slave specified by addr starting from the memory address specified by
memaddr. The number of bytes read is the length of buf. The argument addrsize specifies the
Write buf to the slave specified by addr starting from the memory address specified by memaddr.
The argument addrsize specifies the address size in bits.
The method returns None.
Note buf should be a bytearray type object.
Sample programs
The following sample program applies to the HDC1080 I2C temperature and humidity sensor. This
sensor is available on the XBIB-CU-TH, XBIB-C-MMT, and XBIB-C-SMT XBee development boards.
Note Refer to the HDC1080 datasheet available at ti.com for detailed technical information.
Make the following connections for this example:
XBee pinDescriptionHDC1080 pin
DIO1SCL6
DIO11SDA1
VCCVCC5
GNDND2
# Simple HDC1080 I2C Example
from micropython import const
from machine import I2C
from time import sleep
""" Initialize a HDC1080 temperature and humidity sensor.
Keyword arguments:
i2c -- The i2c object used to interact with the I2C sensor.
slave_addr -- The slave address of the sensor (default 64 or 0x40).
"""
self.i2c = i2c
scan_result = self.i2c.scan()
assert slave_addr in scan_result, \
"Did not find slave %d in scan: %s" % (slave_addr, scan_result)
self.addr = slave_addr
# Sleep for 15 ms to allow the temperature and humidity
# sensors to start recording.
sleep(0.015)
# Set temperature and humidity readings for independent
# operation, 14 bit resolution.
setup_data = 0b00000000
data = bytearray(3)
data[0] = CONF_REG
data[1] = setup_data # Configuration Register [15:8]
""" Read the temperature
Keyword arguments:
celsius -- If True the temperature is returned in Celsius, else
Fahrenheit (default False).
"""
# Set the pointer register to point to the temperature register.
data = bytearray([TEMP_REG])
self.i2c.writeto(self.addr, data)
# Wait for conversion.
sleep(0.01)
data = self.i2c.readfrom(self.addr, 2) # Read two bytes.
# Convert big-endian array of bytes to integer.
value = int.from_bytes(data, "big")
if celsius:
value = (value / (2 ** 16)) * 165 - 40
else:
value = (1.8 * value / (2 ** 16)) * 165 - 40
return value
def read_humidity(self):
""" Read the relative humidity """
# Write to the pointer register, changing it to the humidity
register.
data = bytearray([HUMI_REG])
self.i2c.writeto(self.addr, data)
# Wait for conversion.
sleep(0.01)
data = self.i2c.readfrom(self.addr, 2) # Read two bytes.
# Convert big-endian array of bytes to integer.
value = int.from_bytes(data, "big")
return (value / (2 ** 16)) * 100
x = HDC1080(I2C(1, freq=200000), 64) # This sets up an instance of this
class.
# The high/low temperature registers are 9-bit two's complement signed ints.
# Data is written MSB first, so as an example the value 1 (0b1) is
represented
# as 0b00000000 10000000, or 0x0080.
REGISTER_FORMAT = '>h'
REGISTER_SHIFT = 7
# Read a 9-bit temperature from the DS1621. Values for <protocol>:
#b'0xAA' for Read Temperature
#b'0xA1' for TH Register
#b'0xA2' for TL Register
# Returns temperature in units of 0.5C.Fahrenheit = temp * 9 / 10 + 32
def read_temperature(protocol=b'\xAA'):
i2c.writeto(slave_addr, protocol, False)
data = i2c.readfrom(slave_addr, 2)
value = ustruct.unpack(REGISTER_FORMAT, data)[0] >> REGISTER_SHIFT
return value
# Perform a scan and make sure we find the slave device we want to talk to.
devices = i2c.scan()
assert (slave_addr in devices,
"Did not see slave device address %d in scan result: %s" %
(slave_addr, devices))
display_continuous()
Class Pin
Note This section only applies to devices that support the Pin I/O feature.
Note Only pins D0-P2 are accessible using the Pin class.
You can use the Pin class with the XBee device. For information, see Class Pin: Control I/O pins.
Class UART
Note This section only applies to devices that support the Secondary UART feature.
MicroPython on the XBee Cellular Modem provides access to a 3-wire or 5-wire TTL-level serial port
(referred to as machine.UART(1)) on the following pins. The table also indicates the proper
connections when testing with an FTDI TTL-232R cable. Note that the FTDI cable's pin 3 (VCC) remains
unconnected.
FTDI TTL-232R
XBee
PinNameDescriptionPinName
10GNDGroundN/A1GND
11DIO4Transmit (TX)XBee →5RXD
4DIO12Receive (RX)XBee ←4TXD
18DIO2Ready to Receive (RTS)XBee →2CTS#
17DIO3Clear to Send (CTS)XBee ←6RTS#
Using the RTS and CTS pins for hardware flow control is optional. The XBee Cellular Modem can use
RTS to signal the remote end to stop sending when its receive buffer is close to full, and it will
conversely monitor the CTS signal and only send when the remote end asserts the signal. Both RTS
and CTS are active low signals where 0 (GND) represents "asserted" (or "safe to send") and 1 (VCC)
represents "deasserted" (or "wait to send").
Direction
Test the UART interface
Once you have the hardware set up:
1. Open a terminal window to the MicroPython REPL on your XBee Cellular Modem.
2. Open a second terminal window to the TTL-232R cable you connected to DIO4/DIO12.
Digi MicroPython Programming Guide
82
Page 83
Machine moduleClass UART
3. Leave DIO2/DIO3 disconnected and configure the second terminal window without any flow
control.
4. From the REPL prompt, press Ctrl-E to enter paste mode.
5. Paste the following test code (which uses the default baud rate of 115,200).
from machine import UART
import time
u = UART(1)
u.write('Testing from XBee\n')
while True:
uart_data = u.read()
if uart_data:
print(str(uart_data, 'utf8'), end='')
time.sleep_ms(5)
6. Press Ctrl-D on a blank line to execute it.
7. You should see the message Testing from XBee in the other terminal window, and anything
you type there should appear in your MicroPython terminal.
8. From the MicroPython terminal, use Ctrl-C to send a KeyboardInterrupt and exit the while
loop.
Use the UARTclass
UART implements the standard UART/USART duplex serial communications protocol. At the physical
level it consists of at least two lines: RX and TX, with support for optional hardware flow control using
RTS/CTS handshaking. The unit of communication is a character (not to be confused with a string
character) which can be 5 to 8 bits wide.
Create UART objects using the machine.UART() class:
from machine import UART
uart = UART(1, 9600)# create with given baudrate
uart.init(9600, bits=8, parity=None, stop=1) # reconfigure with given
parameters
A UART object acts like a stream object and uses the standard stream methods for reading and
writing.
uart.read(10)# read 10 characters, returns a bytes object
uart.read()# read all available characters
uart.readline()# read a line
uart.readinto(buf)# read and store into the given buffer
uart.write('abc')# write the 3 characters
To check if there is anything to be read, use:
uart.any()# returns the number of characters waiting
Constructors
class machine.UART(id, baudrate=115200, bits=8, parity=None, stop=1, *, flow=0, timeout=0,
timeout_char=0)
Digi MicroPython Programming Guide
83
Page 84
Machine moduleClass UART
n id: XBee Cellular supports a single UART, using the id 1.
n baudrate: Clock rate for serial data.
n bits: Bits per character, a value from 5 to 8.
n parity: An additional parity bit added to each byte, either None, 0 (even) or 1 (odd).
n stop: Number of stop bits after the optional parity bit, either 1 or 2.
n flow: Hardware flow control; either 0 for none, UART.RTS for RTS-only, UART.CTS for CTS-only
or UART.RTS|UART.CTS for both.
n timeout: Number of milliseconds to wait for reading the first character.
n timeout_char: Number of milliseconds to wait between characters when reading.
You can pass parameters before the flow keyword without their names, for example: UART(1,
115200, 8, None, 1).
Note Unlike other MicroPython platforms, the XBee Cellular Modem uses a circular buffer to store
serial data, and the timeout and timeout_char settings do not apply to writes.
See Constructors for descriptions of each keyword. The default values (used if a keyword is not
specified) leave the current setting unchanged. Calling UART.init() resets the port using the current
settings.
UART.deinit()
Turn off the UART bus. After calling deinit(), attempts to write to the UART result in an OSError
(EPERM) exception but reads continue to pull buffered bytes.
UART.any()
Returns an integer value of the number of bytes in the read buffer, or 0 if no bytes are available.
UART.read([nbytes])
Read characters. If nbytes is specified and a positive value, then read at most that many bytes,
otherwise read as much data as possible.
Return value: a bytes object containing the bytes read. Returns None on timeout.
UART.readinto(buf[, nbytes])
Read bytes into the buf. If nbytes is specified then read at most that many bytes. Otherwise, read at
most len(buf) bytes.
Return value: number of bytes read and stored into buf or None on timeout.
UART.readline()
Read a line, ending in a newline character.
Return value: the line read or None on timeout.
UART.write(buf)
Write the buffer of bytes to the bus.
Return value: number of bytes written.
Constants
Used to specify the flow control type.
Digi MicroPython Programming Guide
84
Page 85
Machine moduleClass WDT: watchdog timer
UART.RTS
UART.CTS
Class WDT: watchdog timer
XBee 3 Cellular devices with firmware ending in *15 or newer and XBee3 DigiMesh, 802.15.4, or ZigBee
devices with firmware ending in *0A or newer contain the machine.WDT() object. It is primarily the
same as documented at wipy/library/machine.WDT. One primary difference is the addition of aresponse parameter to the constructor. This allows you to select the behavior of the system when
the watchdog timer expires without being fed.
On XBee 3 DigiMesh, 802.15.4, or Zigbee devices, the default timeout for the watchdog is five seconds.
On XBee 3 Cellular devices, the default timeout has changed to one minute as blocking operations on
cellular can normally take many seconds to complete and in an initial attempt to use the watchdog
should not cause a reset.
The sleep_now and clean_shutdown operations which can be very lengthy will not trigger a
watchdog reset while in progress and the watchdog timer will have the full timeout upon coming out
of sleep.
Valid choices are:
n SOFT_RESET: resets only the MicroPython interpreter as if the soft_reset method in the device
had been called.
n HARD_RESET: Reboots the entire XBee device.
n CLEAN_SHUTDOWN: Shuts down the cellular component and then reboots. If the cellular
component cannot be cleanly shut down in two minutes it is reset anyway.
Note The CLEAN_SHUTDOWN option is only available on XBee 3 Cellular devices.
Access the XBee device's I/O pins
You can access the XBee device's I/O pins using the Pin class from the machine module. To get
started, import that class and use the help() function to display available methods and constants. The
REPL sessions below all assume you have started with from machine import Pin.
>>> from machine import Pin
>>> help(Pin)
object <class 'Pin'> is of type type
init -- <function>
value -- <function>
off -- <function>
on -- <function>
toggle -- <function>
name -- <function>
names -- <function>
af_list -- <function>
mode -- <function>
pull -- <function>
af -- <function>
mapper -- <classmethod>
dict -- <classmethod>
board -- <class 'board'>
DISABLED -- 15
From the list above, you can see the current configuration of all the pins. Note that pins P0 through P9
have aliases of D10 through D19. Also, through-hole XBee 3 RF products (802.15.4, DigiMesh and
Zigbee) still list pins P5 through P9 even though they are only accessible on the surface-mount
products.
You can assign any of the Pin.board objects to a variable that is easier to type (for example, d0 =
Pin.board.D0) or more descriptive (for example, status_led = Pin.board.D3). Multiple names for a pin
all reference the same physical pin, so changes made through one name appear in all other names.
For example, to change pin D0 from operating as a commissioning button, you could do the following:
The names button and Pin.board.D0 both show the new configuration after using the mode()
method to make it an input. The example keeps the configuration of an internal pull up to Vcc to
simplify the button wiring—just short the pin to ground when you press the button. You can check the
status of the button using the value() method. It returns 0 when pressed (shorted to ground) and 1
otherwise (pulled up to Vcc).
Use the Pin() constructor
Use Pin(name, mode, pull=None, *, value, alt) to create a new Pin object with a specific
configuration. The name parameter can be a string (for example, D0) or reference to an existing Pin
object (for example, Pin.board.D0).
Note By default pull is set to None and will disable a pull up/down resistor already configured for a
given pin.
The documentation for mode(), pull(), and value() also apply to those parameters in the Pin()
constructor. See Pin.ALT for usage of the alt parameter.
Use mode() to configure a pin
Note Using the Pin() constructor to change the mode() of a pin will automatically update the
corresponding AT command value to match and vice-versa. For example, setting pin D11 to disabled
sets the P1 AT command to 0.
Pin.DISABLED
If you are not using a pin, configure it as Pin.DISABLED.
Digi MicroPython Programming Guide
87
Page 88
Machine moduleUse mode() to configure a pin
Pin.IN
Pin acts as an input that you can read with the value() method, which returns 1 for high and 0 for low.
See the pull() method for configuring an internal pull up/down resistor on input pins.
>>> button = Pin.board.D0
>>> button.mode(Pin.IN)
>>> button.pull(Pin.PULL_UP)
>>> # or: button = Pin('D0', mode=Pin.IN, pull=Pin.PULL_UP)
>>> button
Pin(Pin.board.D0, mode=Pin.IN, pull=Pin.PULL_UP)
>>> Pin.board.D0
Pin(Pin.board.D0, mode=Pin.IN, pull=Pin.PULL_UP)
>>> button.value()
1
>>> # hold button and then read value again
>>> button.value()
0
Pin.OUT
Pin acts as an output that you can set by passing a parameter to the value() method. Any value that
evaluates to True sets the pin high (Vcc) and all other values set it low (ground). Pin objects also
support the on() and off() methods as shortcuts for value(1) and value(0) respectively, and toggle()
to toggle the current value. For example, you can override the association indicator normally
configured for D5 and control it manually:
>>> d5 = Pin.board.D5
>>> d5.mode(Pin.OUT)
>>> # turn LED off
>>> d5.value(0)
>>> # turn LED on
>>> d5.value(1)
>>> # turn LED off
>>> d5.off()
>>> # turn LED on
>>> d5.on()
>>> # flash the LED at 2Hz (on .25 seconds, off .25 seconds)
>>> import time
>>> while True:
...d5.toggle()
...time.sleep(.25)
...
Traceback (most recent call last):
File "<stdin>", line 3, in <module>
KeyboardInterrupt:
>>>
Note Using the on() and off() names in your code could be confusing when using outputs wired as
"active low."
Pin.ALT
Selects an alternate function for the pin. Use the af_list() method on a Pin object for a list of
alternate functions available on a pin. You can select a pin's default alternate function by calling mode
(Pin.AF), but you need to use the Pin() constructor to select a specific alternate function if a pin
supports more than one. Use the af() method to see what a Pin's current alternate function is. Note
Digi MicroPython Programming Guide
88
Page 89
Machine moduleUse pull() to configure an internal pull up/down resistor
that af() returns an integer that you should compare to the Pin.AFx_XXX constants in your code, and
not reference directly as they may change between firmware releases.
Use the machine.ADC() class instead of configuring a pin mode as Pin.ANALOG. A Pin object in use by
the ADC() class reports its mode as Pin.ANALOG.
>>> import machine
>>> a1 = machine.ADC('D1')
>>> # read analog input as value from 0-4095
>>> a1.read()
4095
>>> Pin.board.D1
Pin(Pin.board.D1, mode=Pin.ANALOG)
Pin.OPEN_DRAIN and Pin.ALT_OPEN_DRAIN
These modes from other MicroPython platforms are not supported on XBee products.
Use pull() to configure an internal pull up/down resistor
You typically only enable an internal pull up/down resistor on an input to keep it from floating.
Enabling, disabling, or changing the state of a pull up/down resistor using the Pin() constructor will
automatically update the PR and PD parameter values and vice-versa. The Pin.pull() method and
pull parameter to the Pin() constructor take a single parameter:
n None: disable the internal resistor
n Pin.PULL_DOWN: enable a pull down to ground
n Pin.PULL_UP: enable a pull up to Vcc
Digi MicroPython Programming Guide
89
Page 90
digi.ble module
Thedigi.ble module provides interaction with the Bluetooth Low Energy (BLE) functionality of the
XBee device.
You can import thedigi.ble module as follows:
from digi import ble
If you prefer, you can also use thedigi.ble module as follows:
import digi
# Example: disable BLE functionality.
digi.ble.active(False)
Feature support91
active()91
config()92
disconnect_code()93
gap_connect()93
gap_connection methods94
UUID()101
gap_scan()102
gap_scan methods102
gap_scan advertisement format103
Use gap_scan as an iterator103
Use gap_scan as a context manager104
gap_advertise()104
xbee_connect()105
xbee_connection methods106
digi.ble samples106
Troubleshooting107
Digi MicroPython Programming Guide
90
Page 91
digi.ble moduleFeature support
Feature support
The following table shows which devices support the digi.ble module.
FeatureXBee 3 Cellular XBee 3 Zigbee
active()Firmware
ending in *15 or
higher
config()Firmware
ending in *15 or
higher
delete_
bondings()
gap_scan() Firmware
gap_
advertise()
gap_
connect()
Firmware
ending in *15 or
higher
ending in *15 or
higher
Firmware
ending in *15 or
higher
Firmware
ending in *15 or
higher
Firmware 1009 or laterFirmware
1009:config('mac')
100A or later:config('mac'), updating
configuration
100AFirmware
1009Firmware
1009Firmware
100AFirmware
XBee 3
802.15.4
200A and
later
Firmware
200A and
later
200A and
later
200A and
later
200A and
later
200A and
later
XBee 3
DigiMesh
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
XBee
Cellular
Not
supported
Not
supported
Not
supported
Not
supported
Not
supported
Not
supported
io_
callbacks()
passkey_
confirm()
passkey_
enter()
secure()Firmware
xbee_
connect()
active()
Use this function to set or query whether BLE functionality is enabled on the XBee device. This method
is equivalent to the ATBT command.
Firmware
ending in *15 or
higher
Firmware
ending in *15 or
higher
Firmware
ending in *15 or
higher
ending in *15 or
higher
Firmware
ending in *16 or
higher
100AFirmware
200A and
later
100AFirmware
200A and
later
100AFirmware
200A and
later
100AFirmware
200A and
later
100B and later200B and
later
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
Firmware
300A and
later
300B and
later
Not
supported
Not
supported
Not
supported
Not
supported
Not
supported
Digi MicroPython Programming Guide
91
Page 92
digi.ble moduleconfig()
ble.active([mode])
Without parameters:
n ReturnsTrue if BLE is enabled on the XBee device (ATBT = 1).
n ReturnsFalse if BLE is disabled on the XBee device (ATBT = 0).
With parameters:
n True: Enable BLE functionality.
n False: Disable BLE functionality.
config()
Query a BLE configuration value by name,orupdate one or more BLE configuration values.
To query a BLE configuration value, pass the name of the value as a string. Currently supported values
are:
n "mac": Returns the device BLE MAC address, as abytes object.
n "interval_ms": Initial connection interval to use on future GAP connections, as an integer.
n "latency": Initial slave latency value to use on future GAP connections, as an integer.
n "timeout_ms": Initial connection supervision timeout to use on future GAP connections, as an
integer.
Update configuration values
To update one or more BLE configuration values, pass the value(s) as keyword argument(s).config
returnsNone—in other words it has no return value—when updating settings.
<interval_ms>
Update the initial connection interval to use on future GAP connections—seegap_connect().
The connection interval is the time between two data transfer events on the GAP connection. The
value will be rounded down to the nearest multiple of 1.25 milliseconds.interval_msmay be between
8 and 4000 (4 seconds).
Default value (restored at XBee power-up): 50 milliseconds.
<latency>
Update the initial slave latency to use on future GAP connections—seegap_connect().
The slave latency is the number of consecutive connection events that the connected peripheral is
allowed to skip before the connection is dropped.latencymay be between 0 and 500.
Default value (restored at XBee power-up): 0.
Digi MicroPython Programming Guide
92
Page 93
digi.ble moduledisconnect_code()
<timeout_ms>
Update the initial connection supervision timeout to use on future GAP connections—seegap_connect
().
The connection supervision timeout value is the time that the central device (in this case, the XBee)
will wait for a data transfer before assuming that the connection is lost.timeout_msmay be between
100 and 32000 (32 seconds).timeout_msmust be larger than2 * interval_ms * (latency + 1).
Default value (restored at XBee power-up): 1000 milliseconds (1 second).
disconnect_code()
When called on a connection which has been closed, returns a value from the Bluetooth Core
specification Vol 2, Part D (Error Codes) indicating the reason for the disconnect. Calling this on an open
connection returns zero.
The most common values to see here include:
8 - Connection timeout
19 - Remote user terminated
22 - Connection terminated by local host
gap_connect()
Connect to a BLE device. The address type and the address are required arguments.
* ble.ADDR_TYPE_PUBLIC_IDENTITY and ble.ADDR_TYPE_RANDOM_IDENTITY are removed in
802.15.4’s 0x200B release and removed in Zigbee’s 0x300B release. These constants are going to be
removed from future releases of DigiMesh and Cellular firmwares so we do not advise using them.
<address>
The<address> parameter is a bytesobject which represents the BLE MAC address that is the target
of the connection.
Digi MicroPython Programming Guide
93
Page 94
digi.ble modulegap_connection methods
<timeout_ms>
The<timeout_ms> parameter specifies the timeout before giving up on a connection. When a
connection times out, OSError ETIMEDOUT is raised.
Note The connection attempt will automatically time out if the remote peripheral does not respond to
a connection request within six connection intervals—see the <interval_ms> parameter.
<interval_us>, <window_us>
Use<interval_us> and<window_us> to optionally configure the duty cycle to scan for the remote
device. The scanner will run for<window_us> microseconds every<interval_us> microseconds.
The default interval and window are 20 milliseconds and 11.25 milliseconds, respectively. Both values
must be at least 2,500 microseconds (2.5 milliseconds) and no more than approximately 40.96
seconds (40,959,375 microseconds).
<onclose>
The <onclose> parameter assigns a function as a callback to be triggered on receiving a close event
on the connection. The onclose function will be called with two arguments, the ble_connection object
that received the disconnect event and the disconnect code.
Note The supplied disconnect code is also stored on the ble_connection object itself, see disconnect_
code() for more information on disconnect codes.
Return value
If the GAP connect operation is started successfully, agap_connection object is returned.
If the GAP connect operation is not successful, an OSError is raised.
gap_connection methods
The methods available on agap_connection object—returned by thegap_connect()\ function—are
as follows.
gattc_services()
Discover Generic Attribute Profile (GATT) services in the remote device's database. A specific service
can be discovered by specifying the UUID of the service.
connection.gattc_services([, uuid])
<uuid>
The <uuid>parameter is either aUUID object or a value that can construct aUUIDobject. When
specified, the iterator only returns the service with that UUID, otherwise all services are returned.
Return value
If the GATT service discovery operation is successful, an iterator is returned containingtuples with the
following information about each discovered service:
Digi MicroPython Programming Guide
94
Page 95
digi.ble modulegap_connection methods
(handle, uuid)
<handle>
The <handle>is an integer used to reference the service.
<uuid>
The <uuid>is anUUID object.
If theGATT service discovery operation is not able to be started, an OSError is raised.
gattc_characteristics()
Discover GATT characteristics of a service in the remote device's database. A specific characteristic
can be discovered by specifying the UUID of the characteristic.
connection.gattc_characteristics(service[, uuid])
<service>
The <service> parameter is aservice handle discovered from gattc_services().
<uuid>
The <uuid>parameter is either aUUID object or a value that can construct aUUIDobject.When
specified, the iterator or only returns the characteristic(s) with that UUID, otherwise all
characteristics are returned.
Return value
If the GATT characteristic discovery operation is successful, an iterator is returned containingtuples
with the following information about each discovered characteristic:
(handle, uuid, properties)
<handle>
The <handle>is an integer used to reference the characteristic.
<uuid>
The <uuid>is anUUID object.
<properties>
<properties> is an integer containing the property flags. These flags are defined as constants in the
digi.ble module.
They are the following:
n PROP_BROADCAST
n PROP_READ
n PROP_WRITE_NO_RESP
n PROP_WRITE
n PROP_NOTIFY
n PROP_INDICATE
n PROP_AUTH_SIGNED_WR
Digi MicroPython Programming Guide
95
Page 96
digi.ble modulegap_connection methods
If theGATT characteristic discovery operation is not able to be started, an OSError is raised.
gattc_descriptors()
Return an iterator of all GATT descriptors of a characteristic in the remote device's database. Note
that this returns an iterator and the descriptor discovery will not be completed until the iterator is
emptied.
connection.gattc_descriptors(characteristic)
<characteristic>
The<characteristic>parameter is a characteristic handle discovered fromgattc_characteristics.
Return value
If the GATT descriptor discovery operation is successful, an iterator is returnedcontainingtuples with
the following information about each discovered descriptor:
(handle, uuid)
<handle>
The <handle>is an integer used to reference the descriptor.
<uuid>
The <uuid>is anUUID object.
If theGATT descriptor discovery operation is not able to be started, an OSError is raised.
gattc_read_characteristic()
Issue a remote read to the connected peripheral to the specified characteristic.
The <characteristic_handle> parameter is acharacteristic handlediscovered from gattc_
characteristics.
Return value
gattc_read_characteristic returns a bytes object containing the characteristic attribute value.
If the characteristic passed in is invalid or the connection to the peripheral device is lost, an OSError is
raised.
If the required read permissions for the characteristic are not met then an empty bytes object is
returned.
gattc_configure()
Enable or disable notifications/indications for a given characteristic. This configures the remote server
to send notifications/indications and registers the passed callback to be called when one is received.
The <characteristic_handle> parameter is acharacteristic handlediscovered from gattc_
characteristics, whose characteristic has the notify property—ble.PROP_NOTIFY—or the indicateproperty—ble.PROP_INDICATE.
<callback>
The<callback>parameter is a user defined callback that is called whenever a notification or
indication is received from the passed characteristic.
This callback should have two parameters. The first is the data, a bytes object. The second is an
integer indicating the offset of the data.
IfNone is passed as the <callback>parameter or <callback>is not specified, notifications/indications
are disabled for the characteristic.
<notification>
The<notification>parameter is an optional parameter used to distinguish between using
notifications instead of indications. By default, indications are used. If<notification>is set to True,
notifications are used instead of indications.
Note Notifications are unacknowledged by the client and do not guarantee delivery of the data.
gattc_read_descriptor()
Issue a remote read to the connected peripheral to the specified descriptor.
The connection interval is the time between two data transfer events on the GAP connection. The
value will be rounded down to the nearest multiple of 1.25 milliseconds.interval_msmay be between
8 and 4000 (4 seconds).
Default value (restored at XBee power-up): 50 milliseconds.
<latency>
The slave latency is the number of consecutive connection events which the connected peripheral is
allowed to skip before the connection is dropped.latencymay be between 0 and 500.
Default value (restored at XBee power-up): 0.
<timeout_ms>
The connection supervision timeout value is the time that the central device—in this case, the XBee—
will wait for a data transfer before assuming that the connection is lost.timeout_msmay be between
100 and 32000 (32 seconds).timeout_msmust be larger than2 * timeout_ms * (latency + 1).
Default value—restored at XBee power-up: 1000 milliseconds (1 second).
If the configuration could not be updated, an OSError is raised.
security
The security argument takes a bit mask of the following values:
n PAIRING_REQUIRE_MITM: If set, MITM protection must be used during the pairing process. It
is an error to attempt to set this flag when no I/O callbacks have been set yet with the io_callbacks() method.
n PAIRING_REQUIRE_BONDING: Require the use of bonding to enable encryption. When
connections are secured bonding table entries are created to remember the negotiated keys
for future sessions. The device will remember up to 13 bonding table entries. If an attempt to
Digi MicroPython Programming Guide
99
Page 100
digi.ble modulegap_connection methods
bond with additional devices occurs when the bonding table is full the least recently used
bonding table entry is dropped to allow insertion of the new entry.
n PAIRING_DISABLE_LEGACY: Disables the use of legacy pairing when securing the connection,
only LE Secure Connections will be used.
isconnected()
Determines whether BLE is connected to a BLE peripheral device.
connection.isconnected()
Return value
isconnected returns True if the BLE is connected to BLE peripheral device, False otherwise.
secure()
Performs pairing/bonding on a connection.
secure(secure_cb)
<secure_cb>
A callback which is called upon completion of the pairing operation. It is passed the value zero if the
pairing succeeded, otherwise it is passed an error code as documented in the BLE Core specification.
Values between 0-127 are from Vol 11, Part F. Values from 128-255 are Pairing Errors and can be seen
in Vol 3, Part H, section 3.5.5 in Table 3.7.
See also the security argument to ble.config to guide the behavior of the pairing/bonding operation.
io_callbacks()
Provide callbacks that define IO capabilities for pairing.
Callback to be used to present a passkey to the user.
<confirm_cb>
Callback to be used when the user must confirm (Y/N) a passkey. The passkey is provided as an
argument. The passkey should be presented to the user and the user's input should be fed back using
ble.passkey_confirm.
Note If you are providing a display_cb and request_cb, you must provide a confirm_cb. Based on the
I/O capabilities of the peer it may be necessary to perform either input or confirmation of a passkey.
<request_cb>
Callback to indicate that the user must input a passkey value. The user should be prompted to enter a
passkey and the passkey provided by the user should be fed back using ble.passkey_enter.
Digi MicroPython Programming Guide
100
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.