diff --git a/content/_index.md b/content/_index.md
index a58500f..826ad1b 100644
--- a/content/_index.md
+++ b/content/_index.md
@@ -1,16 +1,54 @@
---
title: "Introduction"
aliases:
- - /introduction
-disable_breadcrumbs: true
+ - pybytes/introduction
---
-Welcome to the Pycom documentation site. We recommend reading through all the sections to familiarise yourself with the various tools and features available to you to help you develop on your Pycom module.
+Pycom ecosystem makes IoT development easy.
-To get started, read through the Getting Started guide then feel free to jump straight into the tutorials and examples in Tutorials & Examples to begin building your projects.
+* Choose [IoT hardware](products) which fit your project requirements.
+* Install Pymakr plugin in [Atom](https://atom.io/packages/pymakr) or [VS Code](https://marketplace.visualstudio.com/items?itemName=pycom.Pymakr) and start with your IoT project in seconds.
+
+* Write [MicroPython](https://micropython.org/) code and up to three times faster compared to C/C++.
+
+* Send data to [Pybytes IoT platform](https://pybytes.pycom.io/?utm_source=docs&utm_medium=web&utm_campaign=getting-started-top) or use your device standalone with the range of supported networks.
+
+
+
+## [Setting up the hardware](gettingstarted/connection)
+Firstly we will cover how to connect the module to your computer either via USB or WiFi.
+Secondly, we will explain how to connect various accessories such as antennas or SIM cards to your module.
+
+## [Setting up your computer and Pymakr plugin](gettingstarted/installation)
+You will need to install some software on your computer to interface with it.
+The second part of this guide will guide you through installing drivers and performing firmware updates for your module/accessories.
+And how to set up the Pymakr plugins and other software use to program your device.
+
+## [MicroPython crash course](/gettingstarted/programming)
+Now that you have a connected module and all the required software installed it is time to begin programming your device.
+This part of the guide will get you started with a basic example and point you in the right direction for getting your device connected to your chosen network.
+
+## [Connecting to Pybytes IoT platform](pybytes/introduction)
+Connect your device to [Pybytes](https://pybytes.pycom.io/?utm_source=docs&utm_medium=web&utm_campaign=getting-started-bottom) with Wi-Fi, LoRa or Sigfox. Send data from your device just with one line command.
+Update your firmware over the air and integrate with third-party services like AWS.
+
+## [Connecting to your custom IoT platform](/gettingstarted/registration)
+Connect your device to your own IoT platform with one of the advertised wireless networks.
+This usually requires some registration. This step will detail how to get registered and connected to various wireless networks.
+
+# Quick navigation
* [Products](products)
-* [Getting Started](gettingstarted/introduction)
+* [Pymakr](pymakr/installation)
* [Tutorials](tutorials/introduction)
-* [Product Info](datasheets/introduction)
* [API Documentation](firmwareapi/introduction)
+* [Product Info](datasheets/introduction)
* [Pybytes](pybytes/introduction)
+
+
+
+
+
+
+ Next
+
+
\ No newline at end of file
diff --git a/content/advance/cli.md b/content/advance/cli.md
index 41d55a4..2e7e960 100644
--- a/content/advance/cli.md
+++ b/content/advance/cli.md
@@ -5,6 +5,7 @@ aliases:
- advance/cli.md
- chapter/advance/cli
---
+
## Command Line Update Utility
#### Windows
@@ -330,7 +331,7 @@ To restore your OTA block: `$pycom-fwtool-cli -p PORT ota -r -f backup.ota`
#### lpwan
-Get/Set LPWAN parameters saved to non-volatile storage. Please see [here](/firmwareapi/pycom/network/lora.md##loranvramsave) for more details.
+Get/Set LPWAN parameters saved to non-volatile storage. Please see [here](/firmwareapi/pycom/network/lora#loranvramsave) for more details.
```text
usage: pycom-fwtool-cli -p PORT lpwan [-h] [--region REGION]
@@ -363,4 +364,3 @@ usage: pycom-fwtool-cli erase_all [-h]
optional arguments:
-h, --help show this help message and exit
```
-
diff --git a/content/advance/downgrade.md b/content/advance/downgrade.md
index 2937bbc..f3d38c4 100644
--- a/content/advance/downgrade.md
+++ b/content/advance/downgrade.md
@@ -4,7 +4,9 @@ aliases:
- advance/downgrade.html
- advance/downgrade.md
- chapter/advance/downgrade
+
---
+
The firmware upgrade tool usually updates your device to the latest available firmware version. If you require to downgrade your device to a previous firmware there are two methods to achieve this.
{{% hint style="info" %}}
@@ -21,7 +23,7 @@ You can obtain previous firmware versions here:
* [LoPy4](https://software.pycom.io/downloads/LoPy4.html)
{{% hint style="info" %}}
-Prior to version `1.16.0.b1` the firmware for modules with LoRa functionality was frequency specific. From `1.16.0.b1` and onward, the firmware is region agnostic and this can either be set programatically or via the config block (see [here](../cli#lpwan)).
+Prior to version `1.16.0.b1` the firmware for modules with LoRa functionality was frequency specific. From `1.16.0.b1` and onward, the firmware is region agnostic and this can either be set programatically or via the config block (see [here](../cli.md#lpwan)).
{{< /hint >}}
## GUI
diff --git a/content/advance/encryption.md b/content/advance/encryption.md
index 885f631..4fdd3b3 100644
--- a/content/advance/encryption.md
+++ b/content/advance/encryption.md
@@ -5,6 +5,7 @@ aliases:
- advance/encryption.md
- chapter/advance/encryption
---
+
## Summary
In order to encrypt your firmware, you will need to build it from source. Our firmware source code can be found [here](https://github.com/pycom/pycom-micropython-sigfox/), along with instructions on how to build it. Below you will find specific instructions on how generate keys, build and flash encrypted firmware.
diff --git a/content/datasheets/.DS_Store b/content/datasheets/.DS_Store
new file mode 100644
index 0000000..63adeb6
Binary files /dev/null and b/content/datasheets/.DS_Store differ
diff --git a/content/datasheets/_index.md b/content/datasheets/_index.md
index efd3a1e..a162dc8 100644
--- a/content/datasheets/_index.md
+++ b/content/datasheets/_index.md
@@ -1,54 +1,52 @@
---
-title: "Introduction"
+title: ""
aliases:
- datasheets/introduction.html
- datasheets/introduction.md
- - datasheets/introduction
- product-info
- chapter/datasheets
-disable_breadcrumbs: true
---
The follow pages contain all information relating to each product, for examples: pinouts, spec sheets, relevant examples and notes.
## Development Modules
-{{% refname "development/wipy2.md" %}}
+- {{% refname "development/wipy2.md" %}}.
-{{% refname "development/wipy3.md" %}}
+- {{% refname "development/wipy3.md" %}}
-{{% refname "development/lopy.md" %}}
+- {{% refname "development/lopy.md" %}}
-{{% refname "development/lopy4.md" %}}
+- {{% refname "development/lopy4.md" %}}
-{{% refname "development/sipy.md" %}}
+- {{% refname "development/sipy.md" %}}
-{{% refname "development/gpy.md" %}}
+- {{% refname "development/gpy.md" %}}
-{{% refname "development/fipy.md" %}}
+- {{% refname "development/fipy.md" %}}
## OEM modules
-{{% refname "oem/w01.md" %}}
+- {{% refname "oem/w01.md" %}}
-{{% refname "oem/l01.md" %}}
+- {{% refname "oem/l01.md" %}}
-{{% refname "oem/g01.md" %}}
+- {{% refname "oem/g01.md" %}}
-{{% refname "oem/l01\_reference.md" %}}
+- {{% refname "oem/l01_reference.md" %}}
-{{% refname "oem/universal\_reference.md" %}}
+- {{% refname "oem/universal_reference.md" %}}
## Expansion Boards and Shields
-{{% refname "boards/expansion3.md" %}}
+- {{% refname "boards/expansion3.md" %}}
-{{% refname "boards/pytrack.md" %}}
+- {{% refname "boards/pytrack.md" %}}
-{{% refname "boards/pysense.md" %}}
+- {{% refname "boards/pysense.md" %}}
-{{% refname "boards/pyscan.md" %}}
+- {{% refname "boards/pyscan.md" %}}
-{{% refname "boards/expansion2.md" %}}
+- {{% refname "boards/expansion2.md" %}}
-{{% refname "boards/deepsleep/" %}}
+- {{% refname "boards/deepsleep/" %}}
diff --git a/content/docnotes/_index.md b/content/docnotes/_index.md
index 6e9a909..a22edd4 100644
--- a/content/docnotes/_index.md
+++ b/content/docnotes/_index.md
@@ -1,6 +1,7 @@
---
title: ""
aliases:
-disable_breadcrumbs: true
---
+
The Pycom documentation aims to be straightforward and to adhere to typical Python documentation to allow for ease of understanding. However, there may be some unusual features for those not used to Python documentation or that are new to the MicroPython Language. This section of the documentation aims to provide clarity for any of the design specifics that might be confusing for those new to Python and this style of documentation.
+
diff --git a/content/docnotes/introduction.md b/content/docnotes/introduction.md
index 0f19f33..6c52124 100644
--- a/content/docnotes/introduction.md
+++ b/content/docnotes/introduction.md
@@ -5,5 +5,6 @@ aliases:
- docnotes/introduction.md
- chapter/docnotes
---
+
The Pycom documentation aims to be straightforward and to adhere to typical Python documentation to allow for ease of understanding. However, there may be some unusual features for those not used to Python documentation or that are new to the MicroPython Language. This section of the documentation aims to provide clarity for any of the design specifics that might be confusing for those new to Python and this style of documentation.
diff --git a/content/docnotes/mesh-networks.md b/content/docnotes/mesh-networks.md
index f7c78c2..4cc517a 100644
--- a/content/docnotes/mesh-networks.md
+++ b/content/docnotes/mesh-networks.md
@@ -5,5 +5,6 @@ aliases:
- docnotes/mesh-networks.md
- chapter/docnotes/mesh-networks
---
-Mesh Networking is currently under development. Please click [here](/tutorials/lora/lora-mesh) for the documentation. Please keep in mind that this document is still only informational.
+
+Mesh Networking is currently under development. Please click [here](https://docs.pycom.io/tutorials/lora/lora-mesh.html) for the documentation. Please keep in mind that this document is still only informational.
diff --git a/content/docnotes/replscript.md b/content/docnotes/replscript.md
index 31a9db8..0eddb57 100644
--- a/content/docnotes/replscript.md
+++ b/content/docnotes/replscript.md
@@ -5,11 +5,14 @@ aliases:
- docnotes/replscript.md
- chapter/docnotes/replscript
---
+
Users of this documentation should be aware that examples given in the docs are under the expectation that they are being executed using the MicroPython REPL. This means that when certain functions are called, their output may not necessarily be printed to the console if they are run from a script. When using the REPL many classes/functions automatically produce a printed output displaying the return value of the function to the console. The code snippet below demonstrates some examples of classes/functions that might display this behaviour.
## Basic Arithmetic
```python
+
+
1 + 1 # REPL will print out '2' to console
1 + 1 # Script will not return anything the console
print(1 + 1) # Both the REPL and a script will return '2' to the console
@@ -36,4 +39,3 @@ value = 1 + 1
# do something here...
print(value)
```
-
diff --git a/content/docnotes/syntax.md b/content/docnotes/syntax.md
index b47d86a..7c9d136 100644
--- a/content/docnotes/syntax.md
+++ b/content/docnotes/syntax.md
@@ -5,6 +5,7 @@ aliases:
- docnotes/syntax.md
- chapter/docnotes/syntax
---
+
The Pycom documentation follows standard Python Library format using the popular Sphinx Docs tool. There are some notable points regarding the syntax of classes, methods and constants. Please see the notes below and familiarise yourself with the specific details before reviewing the documentation.
## Keyword Arguments
@@ -14,12 +15,14 @@ The Pycom documentation follows standard Python Library format using the popular
The values of the arguments (as seen in the examples/docs) refer to the default values that are passed into the constructor if nothing is provided.
```python
+
i2c.init(mode, * , baudrate=100000, pins=(SDA, SCL))
```
An example of how this method might be called:
```python
+
i2c.init(I2C.MASTER, pins=('P12', 'P11'))
```
@@ -34,10 +37,12 @@ It is important to note that there are certain class methods that can only accep
An astrik `*` in a method description (in the docs), denotes that the following arguments require a keyword, i.e. `pin='P16'` in the example below.
```python
+
adc.channel(* , pin, attn=ADC.ATTN_0DB)
```
```python
+
from machine import ADC
adc = ADC() # create an ADC object
@@ -49,6 +54,7 @@ apin = adc.channel(pin='P16') # create an analog pin on P16
Another example shows how the `PWM` class, `pwm.channel()` requires a keyword argument for `pin` but does not for `id`.
```python
+
from machine import PWM
pwm = PWM(0, frequency=5000)
@@ -60,12 +66,14 @@ pwm_c = pwm.channel(0, pin='P12') # no keyword argument requires for id (0) but
The documentation may refer to a method that takes an argument listed by name but does allow for a keyword to be passed. For example, the `pycom` class contains a method `rgbled`. This lists that the method accepts a value for `color`, however this may not be specified by `keyword`, only `value`. This is intentional as the `value` being passed is the only argument valid for this method
```python
+
pycom.rgbled(color)
```
If the argument is passed into the method with a keyword, it will return an error stating TypeError: function does not take keyword arguments.
```python
+
import pycom
pycom.rgbled(color=0xFF0000) # Incorrect
@@ -75,10 +83,12 @@ pycom.rgbled(0xFF0000) # Correct
Another example of a method that only accepts value input. In this case, the `RTC.init()` method require a value (`tuple`) input for the `datetime`. It will not accept a keyword.
```python
+
rtc.init(datetime)
```
```python
+
from machine import RTC
rtc = RTC()
@@ -91,6 +101,7 @@ rtc.init((2014, 5, 1, 4, 13, 0, 0, 0)) # Correct
The `constants` section of a library within the docs refers to specific values from that library's class. These might be used when constructing an object from that class or when utilising a method from within that class. These are generally listed by the library name followed by the specific value. See the example below:
```python
+
I2C.MASTER()
```
diff --git a/content/documents/_index.md b/content/documents/_index.md
new file mode 100644
index 0000000..3e0f2df
--- /dev/null
+++ b/content/documents/_index.md
@@ -0,0 +1,4 @@
+---
+title: documents
+disable_breadcrumbs: true
+---
diff --git a/content/documents/certificates.md b/content/documents/certificates.md
new file mode 100644
index 0000000..0e16413
--- /dev/null
+++ b/content/documents/certificates.md
@@ -0,0 +1,108 @@
+---
+title: "Certificates"
+aliases:
+ - documents/certificates.html
+ - documents/certificates.md
+---
+
+## CE RED
+
+### Development Boards
+
+#### LoPy
+
+
diff --git a/content/documents/license.md b/content/documents/license.md
new file mode 100644
index 0000000..6143b83
--- /dev/null
+++ b/content/documents/license.md
@@ -0,0 +1,21 @@
+---
+title: "License"
+aliases:
+ - documents/license.html
+ - documents/license.md
+---
+
+The MIT License (MIT)
+
+Copyright (c) 2013-2015 Damien P. George, and others
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Copyright (c) 2017, Pycom Limited.
+
+This software is licensed under the GNU GPL version 3 or any later version, with permitted additional terms. For more information see the Pycom Licence v1.0 document supplied with this file, or available at [https://www.pycom.io/opensource/licensing](https://www.pycom.io/opensource/licensing)
+
diff --git a/content/firmwareapi/_index.md b/content/firmwareapi/_index.md
index 19e32ef..8fc6eb4 100644
--- a/content/firmwareapi/_index.md
+++ b/content/firmwareapi/_index.md
@@ -1,8 +1,11 @@
---
title: ""
aliases:
-disable_breadcrumbs: true
+ - /tutorial/introduction
+ - /tutorial/introduction.md
+
---
+
This chapter describes modules (function and class libraries) that are built into MicroPython. There are a number of categories for the available modules:
* Modules which implement a subset of standard Python functionality and are not intended to be extended by the user.
diff --git a/content/firmwareapi/introduction.md b/content/firmwareapi/introduction.md
index 984187f..f2462e4 100644
--- a/content/firmwareapi/introduction.md
+++ b/content/firmwareapi/introduction.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/introduction.md
- chapter/firmwareapi
---
+
This chapter describes modules (function and class libraries) that are built into MicroPython. There are a number of categories for the available modules:
* Modules which implement a subset of standard Python functionality and are not intended to be extended by the user.
diff --git a/content/firmwareapi/micropython/_index.md b/content/firmwareapi/micropython/_index.md
index ed523ff..68536cf 100644
--- a/content/firmwareapi/micropython/_index.md
+++ b/content/firmwareapi/micropython/_index.md
@@ -2,6 +2,7 @@
title: "MicroPython Modules"
aliases:
---
+
The following list contains the standard Python libraries, MicroPython-specific libraries and Pycom specific modules that are available on the Pycom devices.
The standard Python libraries have been "micro-ified" to fit in with the philosophy of MicroPython. They provide the core functionality of that module and are intended to be a drop-in replacement for the standard Python library.
diff --git a/content/firmwareapi/micropython/_thread.md b/content/firmwareapi/micropython/_thread.md
index d7d9c80..625adf1 100644
--- a/content/firmwareapi/micropython/_thread.md
+++ b/content/firmwareapi/micropython/_thread.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/_thread.md
- chapter/firmwareapi/micropython/_thread
---
+
This module provides low-level primitives for working with multiple threads (also called light-weight processes or tasks) — multiple threads of control sharing their global data space. For synchronisation, simple locks (also called mutexes or binary semaphores) are provided.
When a thread specific error occurs a `RuntimeError` exception is raised.
@@ -12,6 +13,7 @@ When a thread specific error occurs a `RuntimeError` exception is raised.
## Quick Usage Example
```python
+
import _thread
import time
@@ -81,6 +83,7 @@ Return the status of the lock: `True` if it has been acquired by some thread, `F
In addition to these methods, lock objects can also be used via the with statement, e.g.:
```python
+
import _thread
a_lock = _thread.allocate_lock()
diff --git a/content/firmwareapi/micropython/array.md b/content/firmwareapi/micropython/array.md
index e4a8fad..8b64f52 100644
--- a/content/firmwareapi/micropython/array.md
+++ b/content/firmwareapi/micropython/array.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/array.md
- chapter/firmwareapi/micropython/array
---
+
See [Python array](https://docs.python.org/3/library/array.html) for more information.
Supported format codes: `b, B, h, H, i, I, l, L, q, Q, f, d` (the latter 2 depending on the floating-point support).
diff --git a/content/firmwareapi/micropython/builtin.md b/content/firmwareapi/micropython/builtin.md
index 0aa4fc4..cb167ad 100644
--- a/content/firmwareapi/micropython/builtin.md
+++ b/content/firmwareapi/micropython/builtin.md
@@ -5,7 +5,8 @@ aliases:
- firmwareapi/micropython/builtin.md
- chapter/firmwareapi/micropython/builtin
---
-All builtin functions are described here. They are also available via [builtins](../builtin) module.
+
+All builtin functions are described here.
abs()
diff --git a/content/firmwareapi/micropython/cmath.md b/content/firmwareapi/micropython/cmath.md
index 876ad88..6cf720f 100644
--- a/content/firmwareapi/micropython/cmath.md
+++ b/content/firmwareapi/micropython/cmath.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/cmath.md
- chapter/firmwareapi/micropython/cmath
---
+
The `cmath` module provides some basic mathematical functions for working with complex numbers. Floating point support required for this module.
## Methods
diff --git a/content/firmwareapi/micropython/gc.md b/content/firmwareapi/micropython/gc.md
index 675ffbc..6c1afa9 100644
--- a/content/firmwareapi/micropython/gc.md
+++ b/content/firmwareapi/micropython/gc.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/gc.md
- chapter/firmwareapi/micropython/gc
---
+
## Methods
#### gc.enable()
diff --git a/content/firmwareapi/micropython/math.md b/content/firmwareapi/micropython/math.md
index 4347b6b..e0a3550 100644
--- a/content/firmwareapi/micropython/math.md
+++ b/content/firmwareapi/micropython/math.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/math.md
- chapter/firmwareapi/micropython/math
---
+
The math module provides some basic mathematical functions for working with floating-point numbers. Floating point support required for this module.
## Methods
diff --git a/content/firmwareapi/micropython/micropython.md b/content/firmwareapi/micropython/micropython.md
index 5a07cd2..317edc1 100644
--- a/content/firmwareapi/micropython/micropython.md
+++ b/content/firmwareapi/micropython/micropython.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/micropython.md
- chapter/firmwareapi/micropython/micropython
---
+
## Methods
#### micropython.alloc\_emergency\_exception\_buf(size)
@@ -18,6 +19,7 @@ A good way to use this function is to place it at the start of a main script (e.
Used to declare that the expression is a constant so that the compile can optimise it. The use of this function should be as follows:
```python
+
from micropython import const
CONST_X = const(123)
diff --git a/content/firmwareapi/micropython/select.md b/content/firmwareapi/micropython/select.md
index 602a023..e80bca2 100644
--- a/content/firmwareapi/micropython/select.md
+++ b/content/firmwareapi/micropython/select.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/select.md
- chapter/firmwareapi/micropython/select
---
+
This module provides functions to wait for events on streams (select streams which are ready for operations).
## Pyboard specifics
diff --git a/content/firmwareapi/micropython/sys.md b/content/firmwareapi/micropython/sys.md
index bcae70c..72c3aab 100644
--- a/content/firmwareapi/micropython/sys.md
+++ b/content/firmwareapi/micropython/sys.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/sys.md
- chapter/firmwareapi/micropython/sys
---
+
## Methods
#### sys.exit(retval=0)
@@ -42,6 +43,7 @@ CPython mandates more attributes for this object, but the actual useful bare min
This attribute is useful for detecting "bitness" of a platform (32-bit vs 64-bit, etc.). It's recommended to not compare this attribute to some value directly, but instead count number of bits in it:
```python
+
bits = 0
v = sys.maxsize
while v:
diff --git a/content/firmwareapi/micropython/ubinascii.md b/content/firmwareapi/micropython/ubinascii.md
index 9ea2622..7af7140 100644
--- a/content/firmwareapi/micropython/ubinascii.md
+++ b/content/firmwareapi/micropython/ubinascii.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/ubinascii.md
- chapter/firmwareapi/micropython/ubinascii
---
+
This module implements conversions between binary data and various encodings of it in ASCII form (in both directions).
## Methods
diff --git a/content/firmwareapi/micropython/ucrypto.md b/content/firmwareapi/micropython/ucrypto.md
index 6037dde..c11b17a 100644
--- a/content/firmwareapi/micropython/ucrypto.md
+++ b/content/firmwareapi/micropython/ucrypto.md
@@ -5,11 +5,12 @@ aliases:
- firmwareapi/micropython/ucrypto.md
- chapter/firmwareapi/micropython/ucrypto
---
+
This module provides native support for cryptographic algorithms. It's loosely based on PyCrypto.
## Classes
-* [class AES](../../pycom/aes) - Advanced Encryption Standard
+* [class AES](/firmwareapi/pycom/aes) - Advanced Encryption Standard
## **Methods**
@@ -24,3 +25,24 @@ The parameter `bits` is rounded upwards to the nearest multiple of 32 bits.
{{% hint style="danger" %}}
Cryptography is not a trivial business. Doing things the wrong way could quickly result in decreased or no security. Please document yourself in the subject if you are depending on encryption to secure important information.
{{< /hint >}}
+
+#### crypto.generate\_rsa\_signature(message, private_key, \*, pers="esp32-tls")
+
+Generates signature for `message` based on `private_key` using RS256 algorithm.
+The `message` is expected as a string.
+The `private_key` is the content of the private key and not the path of it. The private key must be in PKCS8 format!
+The `pers` is the personalization string used for random number generation.
+Returns with a Bytes object containing the generated signature.
+
+```python
+
+import crypto
+
+# Example of a JWT header + payload
+header_payload = "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
+# Private key MUST BE in PKCS8 format !!!
+f = open("cert/private_key_pkcs8.pem")
+pk = f.read()
+# Generate the signature
+signature = crypto.generate_rsa_signature(header_payload, pk, pers="my_pers_string")
+```
diff --git a/content/firmwareapi/micropython/uctypes.md b/content/firmwareapi/micropython/uctypes.md
index ce3951b..07cadaa 100644
--- a/content/firmwareapi/micropython/uctypes.md
+++ b/content/firmwareapi/micropython/uctypes.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/uctypes.md
- chapter/firmwareapi/micropython/uctypes
---
+
This module implements "foreign data interface" for MicroPython. The idea behind it is similar to CPython's `ctypes` modules, but the actual API is different, streamlined and optimised for small size. The basic idea of the module is to define data structure layout with about the same power as the C language allows, and the access it using familiar dot-syntax to reference sub-fields.
{{% hint style="info" %}}
@@ -20,6 +21,7 @@ Following are encoding examples for various field types:
* Scalar types:
```python
+
"field_name": uctypes.UINT32 | 0
```
@@ -28,6 +30,7 @@ In other words, value is scalar type identifier OR-ed with field offset (in byte
* Recursive structures:
```python
+
"sub": (2, {
"b0": uctypes.UINT8 | 0,
"b1": uctypes.UINT8 | 1,
@@ -39,6 +42,7 @@ I.e. value is a 2-tuple, first element of which is offset, and second is a struc
* Arrays of Primitive Types:
```python
+
"arr": (uctypes.ARRAY | 0, uctypes.UINT8 | 2),
```
@@ -47,6 +51,7 @@ I.e. value is a 2-tuple, first element of which is ARRAY flag OR-ed with offset,
* Arrays of Aggregate Types:
```python
+
"arr2": (uctypes.ARRAY | 0, 2, {"b": uctypes.UINT8 | 0}),
```
@@ -55,6 +60,7 @@ I.e. value is a 3-tuple, first element of which is ARRAY flag OR-ed with offset,
* Pointer to a primitive type:
```python
+
"ptr": (uctypes.PTR | 0, uctypes.UINT8),
```
@@ -63,6 +69,7 @@ I.e. value is a 2-tuple, first element of which is PTR flag OR-ed with offset, a
* Pointer to an aggregate type:
```python
+
"ptr2": (uctypes.PTR | 0, {"b": uctypes.UINT8 | 0}),
```
@@ -71,6 +78,7 @@ I.e. value is a 2-tuple, first element of which is PTR flag OR-ed with offset, s
* Bitfields:
```python
+
"bitf0": uctypes.BFUINT16 | 0 | 0 << uctypes.BF_POS | 8 << uctypes.BF_LEN,
```
diff --git a/content/firmwareapi/micropython/uhashlib.md b/content/firmwareapi/micropython/uhashlib.md
index 9ffbef5..bb5f4cc 100644
--- a/content/firmwareapi/micropython/uhashlib.md
+++ b/content/firmwareapi/micropython/uhashlib.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/uhashlib.md
- chapter/firmwareapi/micropython/uhashlib
---
+
This module implements binary data hashing algorithms. MD5 and SHA are supported. By limitations in the hardware, only one active hashing operation is supported at a time.
## Constructors
diff --git a/content/firmwareapi/micropython/ujson.md b/content/firmwareapi/micropython/ujson.md
index 084d581..d62dc47 100644
--- a/content/firmwareapi/micropython/ujson.md
+++ b/content/firmwareapi/micropython/ujson.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/ujson.md
- chapter/firmwareapi/micropython/ujson
---
+
This modules allows to convert between Python objects and the JSON data format.
## Methods
diff --git a/content/firmwareapi/micropython/uos.md b/content/firmwareapi/micropython/uos.md
index 1e272c3..ef6d3b5 100644
--- a/content/firmwareapi/micropython/uos.md
+++ b/content/firmwareapi/micropython/uos.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/uos.md
- chapter/firmwareapi/micropython/uos
---
+
The `uos` module contains functions for filesystem access and `urandom` function.
## Port Specifics
@@ -86,31 +87,16 @@ Alias for the `remove()` method.
Mounts a block device (like an SD object) in the specified mount point. Example:
```python
+
os.mount(sd, '/sd')
uos.unmount(path)
```
Unmounts a previously mounted block device from the given path.
-#### uos.mkfat(block\_device)
+#### uos.mkfs(block\_device or path)
-Instantiate a VFS (Virtual File System) object with underlying FAT file system.
-
-Example:
-
-```python
-from machine import SD
-import os
-sd = SD()
-vfs = os.mkfat(sd) # Creating a VFS
-vfs.mkfs(sd) # Formating the SD card
-# Now we can use normal os mount
-os.mount(vfs, '/sd')
-```
-
-#### uos.fsformat(path)
-
-Formats the block device mounted under the input path, must be either `/flash` or `/sd`
+Formats the specified path, must be either `/flash` or `/sd`. A block device can also be passed like an SD object before being mounted.
#### uos.dupterm(stream\_object)
@@ -119,4 +105,3 @@ Duplicate the terminal (the REPL) on the passed stream-like object. The given ob
## Constants
* `uos.sep`: Separation character used in paths
-
diff --git a/content/firmwareapi/micropython/ure.md b/content/firmwareapi/micropython/ure.md
index 60e4cf1..2fc7c5e 100644
--- a/content/firmwareapi/micropython/ure.md
+++ b/content/firmwareapi/micropython/ure.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/ure.md
- chapter/firmwareapi/micropython/ure
---
+
This module implements regular expression operations. Regular expression syntax supported is a subset of CPython re module (and actually is a subset of POSIX extended regular expressions).
Supported operators are:
diff --git a/content/firmwareapi/micropython/usocket.md b/content/firmwareapi/micropython/usocket.md
index 22cff51..c28f33a 100644
--- a/content/firmwareapi/micropython/usocket.md
+++ b/content/firmwareapi/micropython/usocket.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/usocket.md
- chapter/firmwareapi/micropython/usocket
---
+
This module provides access to the BSD socket interface.
See corresponding CPython module for comparison.
@@ -26,6 +27,7 @@ Translate the host/port argument into a sequence of 5-tuples that contain all th
`(family, type, proto, canonname, sockaddr)` The following example shows how to connect to a given url:
```python
+
s = socket.socket()
s.connect(socket.getaddrinfo('www.micropython.org', 80)[0][-1])
```
@@ -109,6 +111,7 @@ Set blocking or non-blocking mode of the socket: if flag is false, the socket is
This method is a shorthand for certain `settimeout()` calls:
```python
+
sock.setblocking(True) is equivalent to sock.settimeout(None)
sock.setblocking(False) is equivalent to sock.settimeout(0.0)
```
@@ -127,7 +130,7 @@ Closing the file object returned by `makefile()` **WILL** close the original soc
#### socket.read(size)
-Read up to size bytes from the socket. Return a bytes object. If `size` is not given, it behaves just like [`socket.readall()`](../usocket#socket-readall), see below.
+Read up to size bytes from the socket. Return a bytes object. If `size` is not given, it behaves just like [`socket.readall()`](../usocket.md#socket-readall), see below.
#### socket.readall()
@@ -154,7 +157,53 @@ Return value: number of bytes written.
#### socket.do_handshake()
Perform the SSL handshake on the previously "wrapped" socket with ssl.wrap_socket().
-COuld be used when the socket is non-blocking and the SSL handshake is not performed during connect().
+could be used when the socket is non-blocking and the SSL handshake is not performed during connect().
+
+Example:
+
+```
+from network import WLAN
+import time
+import socket
+import ssl
+import uselect as select
+
+wlan = WLAN(mode=WLAN.STA)
+wlan.connect(ssid='', auth=(WLAN.WPA2, ''))
+while not wlan.isconnected():
+ time.sleep(1)
+ print("Wifi .. Connecting")
+
+print ("Wifi Connected")
+
+a = socket.getaddrinfo('www.postman-echo.com', 443)[0][-1]
+s= socket.socket()
+s.setblocking(False)
+s = ssl.wrap_socket(s)
+try:
+ s.connect(a)
+except OSError as e:
+ if str(e) == '119': # For non-Blocking sockets 119 is EINPROGRESS
+ print("In Progress")
+ else:
+ raise e
+poller = select.poll()
+poller.register(s, select.POLLOUT | select.POLLIN)
+while True:
+ res = poller.poll(1000)
+ if res:
+ if res[0][1] & select.POLLOUT:
+ print("Doing Handshake")
+ s.do_handshake()
+ print("Handshake Done")
+ s.send(b"GET / HTTP/1.0\r\n\r\n")
+ poller.modify(s,select.POLLIN)
+ continue
+ if res[0][1] & select.POLLIN:
+ print(s.recv(4092))
+ break
+ break
+```
#### socket.dnsserver(*, dnsIndex, ip_addr)
diff --git a/content/firmwareapi/micropython/ussl.md b/content/firmwareapi/micropython/ussl.md
index 9f6e7c0..1cdfc87 100644
--- a/content/firmwareapi/micropython/ussl.md
+++ b/content/firmwareapi/micropython/ussl.md
@@ -5,15 +5,17 @@ aliases:
- firmwareapi/micropython/ussl.md
- chapter/firmwareapi/micropython/ussl
---
+
This module provides access to Transport Layer Security (often known as "Secure Sockets Layer") encryption and peer authentication facilities for network sockets, both client-side and server-side.
## Methods
-#### ssl.wrap\_socket(sock, keyfile=None, certfile=None, server\_side=False, cert\_reqs=CERT\_NONE, ca\_certs=None)
+#### ssl.wrap\_socket(sock, keyfile=None, certfile=None, server\_side=False, cert\_reqs=CERT\_NONE, ca\_certs=None\, timeout=10sec)
Takes an instance `sock` of `socket.socket`, and returns an instance of ssl.SSLSocket, a subtype of `socket.socket`, which wraps the underlying socket in an SSL context. Example:
```python
+
import socket
import ssl
s = socket.socket()
@@ -26,6 +28,7 @@ Certificates must be used in order to validate the other side of the connection,
For instance, to connect to the Blynk servers using certificates, take the file `ca.pem` located in the `blynk` examples folder and put it in `/flash/cert/`. Then do:
```python
+
import socket
import ssl
s = socket.socket()
@@ -35,12 +38,13 @@ ss.connect(socket.getaddrinfo('cloud.blynk.cc', 8441)[0][-1])
SSL sockets inherit all methods and from the standard sockets, see the `usocket` module.
+`timeout` : specify a Timeout in Seconds for the SSL handshake operation between client and server, default is 10 seconds
+
## Exceptions
-`ssl.SSLError`
+* `ssl.SSLError`
## Constants
* `ssl.CERT_NONE`, `ssl.CERT_OPTIONAL`, `ssl.CERT_REQUIRED`: Supported values in `cert_reqs`
-* `ssl.SSL_TIMEOUT`: raised by a "wrapped" socket when socket.do_handshake() is called
diff --git a/content/firmwareapi/micropython/ustruct.md b/content/firmwareapi/micropython/ustruct.md
index 8f8b276..1480418 100644
--- a/content/firmwareapi/micropython/ustruct.md
+++ b/content/firmwareapi/micropython/ustruct.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/ustruct.md
- chapter/firmwareapi/micropython/ustruct
---
+
See Python [struct](https://docs.python.org/3/library/struct.html) for more information.
Supported size/byte order prefixes: `@, <, >, !`.
diff --git a/content/firmwareapi/micropython/utime.md b/content/firmwareapi/micropython/utime.md
index 2db8865..e781ac9 100644
--- a/content/firmwareapi/micropython/utime.md
+++ b/content/firmwareapi/micropython/utime.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/micropython/utime.md
- chapter/firmwareapi/micropython/utime
---
+
The `utime` module provides functions for getting the current time and date, measuring time intervals, and for delays.
**Time Epoch**: Pycom's ESP32 port uses standard for POSIX systems epoch of `1970-01-01 00:00:00 UTC`.
@@ -66,15 +67,16 @@ Just like `ticks_ms` above, but in microseconds.
Same as `ticks_us`, but faster.
-#### utime.ticks\_diff(end, start)
+#### utime.ticks\_diff(old, new)
-Measure period between consecutive calls to `ticks_ms()`, `ticks_us()`, or `ticks_cpu()`. The value returned by these functions may wrap around at any time, so directly subtracting them is not supported. `ticks_diff()` should be used instead. "start" value should actually precede "end" value in time, or result is undefined. This function should not be used to measure arbitrarily long periods of time (because `ticks_*()` functions wrap around and usually would have short period). The expected usage pattern is implementing event polling with timeout:
+Measure period between consecutive calls to `ticks_ms()`, `ticks_us()`, or `ticks_cpu()`. The value returned by these functions may wrap around at any time, so directly subtracting them is not supported. `ticks_diff()` should be used instead. "old" value should actually precede "new" value in time, or result is undefined. This function should not be used to measure arbitrarily long periods of time (because `ticks_*()` functions wrap around and usually would have short period). The expected usage pattern is implementing event polling with timeout:
```python
+
# Wait for GPIO pin to be asserted, but at most 500us
start = time.ticks_us()
while pin.value() == 0:
- if time.ticks_diff(time.ticks_us(), start) > 500:
+ if time.ticks_diff(start, time.ticks_us()) > 500:
raise TimeoutError
```
diff --git a/content/firmwareapi/notes.md b/content/firmwareapi/notes.md
index e67bc60..160f391 100644
--- a/content/firmwareapi/notes.md
+++ b/content/firmwareapi/notes.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/notes.md
- chapter/firmwareapi/notes
---
+
## Interrupt Handling
In Pycom's ESP32 MicroPython port there are no restrictions on what can be done within an interrupt handler. For example, other ports do not allow allocating memory inside the handler or the use of sockets.
@@ -13,7 +14,7 @@ These limitations were raised by handling the interrupt events differently. When
The user can do whatever is required inside of the callback, such as creating new variables, or even sending network packets. Bear in mind that interrupts are processed sequentially and thus it is ideal to keep the handlers as short as possible in order to attend all of them in the minimum time.
-Currently, there are 2 classes that support interrupts; the [`Alarm`](/firmwareapi/pycom/machine/timer.md#class-timer-alarm-handler-none-s-ms-us-arg-none-periodic-false) and [`Pin`](/firmwareapi/pycom/machine/pin) classes. Both classes provide the `.callback()` method that enables the interrupt and registers the given handler. For more details about interrupt usage along with examples, please visit their respective sections.
+Currently, there are 2 classes that support interrupts; the [`Alarm`](../pycom/machine/timer.md#class-timer-alarm-handler-none-s-ms-us-arg-none-periodic-false) and [`Pin`](../pycom/machine/pin) classes. Both classes provide the `.callback()` method that enables the interrupt and registers the given handler. For more details about interrupt usage along with examples, please visit their respective sections.
{{% hint style="info" %}}
Currently the interrupt system can queue up to **16 interrupts**.
diff --git a/content/firmwareapi/pycom/_index.md b/content/firmwareapi/pycom/_index.md
index b5837bb..faf0e42 100644
--- a/content/firmwareapi/pycom/_index.md
+++ b/content/firmwareapi/pycom/_index.md
@@ -2,5 +2,6 @@
title: "Pycom Modules"
aliases:
---
+
These modules are specific to the Pycom devices and may have slightly different implementations to other variations of MicroPython (i.e. for Non-Pycom devices). Modules include those which support access to underlying hardware, e.g. I2C, SPI, WLAN, Bluetooth, etc.
diff --git a/content/firmwareapi/pycom/aes.md b/content/firmwareapi/pycom/aes.md
index 9767a04..3b2a878 100644
--- a/content/firmwareapi/pycom/aes.md
+++ b/content/firmwareapi/pycom/aes.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/aes.md
- chapter/firmwareapi/pycom/aes
---
+
AES (Advanced Encryption Standard) is a symmetric block cipher standardised by NIST. It has a fixed data block size of 16 bytes. Its keys can be 128, 192, or 256 bits long.
{{% hint style="info" %}}
@@ -14,6 +15,7 @@ AES is implemented using the ESP32 hardware module.
## Quick Usage Example
```python
+
from crypto import AES
import crypto
key = b'notsuchsecretkey' # 128 bit (16 bytes) key
diff --git a/content/firmwareapi/pycom/machine/README.md b/content/firmwareapi/pycom/machine/README.md
index 866021b..e821df1 100644
--- a/content/firmwareapi/pycom/machine/README.md
+++ b/content/firmwareapi/pycom/machine/README.md
@@ -3,11 +3,13 @@ title: "machine"
aliases:
- chapter/firmwareapi/pycom/machine
---
+
The `machine` module contains specific functions related to the board.
### Quick Usage Example
```python
+
import machine
help(machine) # display all members from the machine module
@@ -45,26 +47,15 @@ Returns CPU frequency in hertz.
Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
-#### machine.sleep(\[time\_ms\], resume\_wifi\_ble)
-
-Sets the device in to light sleep mode , where in this mode digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
-
-* `time_ms` is the time in milliseconds that the device should wakeup after, if no time is given the device will sleep until the next reset cycle unless another wakeup source is configured.
-* `resume_wifi_ble` is a boolean value that enables or disable restoring after wakeup any WiFi or BLE connection that was interrupted by light sleep.
-* `True` Enable WiFi/BLE connections restoration
-* `False` Disable Wifi/BLE connections restoration, default option is Disabled
-
-_Note: in light sleep mode LoRa/Lte modems are stopped and have to be re-initialized after wakeup._
-
#### machine.deepsleep(\[time\_ms\])
Stops the CPU and all peripherals, including the networking interfaces (except for LTE). Execution is resumed from the main script, just as with a reset. If a value in milliseconds is given then the device will wake up after that period of time, otherwise it will remain in deep sleep until the reset button is pressed.
The products with LTE connectivity (FiPy, GPy, G01), require the LTE radio to be disabled separately via the LTE class before entering deepsleep. This is required due to the LTE radio being powered independently and allowing use cases which require the system to be taken out from deepsleep by an event from the LTE network (data or SMS received for instance).
-#### machine.pin\_sleep\_wakeup(pins, mode, enable\_pull)
+#### machine.pin\_deepsleep\_wakeup(pins, mode, enable\_pull)
-Configure pins to wake up from deep/light sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
+Configure pins to wake up from deep sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
The arguments are:
diff --git a/content/firmwareapi/pycom/machine/_index.md b/content/firmwareapi/pycom/machine/_index.md
index 8b5faae..794842c 100644
--- a/content/firmwareapi/pycom/machine/_index.md
+++ b/content/firmwareapi/pycom/machine/_index.md
@@ -2,11 +2,13 @@
title: "machine"
aliases:
---
+
The `machine` module contains specific functions related to the board.
### Quick Usage Example
```python
+
import machine
help(machine) # display all members from the machine module
@@ -44,26 +46,15 @@ Returns CPU frequency in hertz.
Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
-#### machine.sleep(\[time\_ms\], resume\_wifi\_ble)
-
-Sets the device in to light sleep mode , where in this mode digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
-
-* `time_ms` is the time in milliseconds that the device should wakeup after, if no time is given the device will sleep until the next reset cycle unless another wakeup source is configured.
-* `resume_wifi_ble` is a boolean value that enables or disable restoring after wakeup any WiFi or BLE connection that was interrupted by light sleep.
-* `True` Enable WiFi/BLE connections restoration
-* `False` Disable Wifi/BLE connections restoration, default option is Disabled
-
-_Note: in light sleep mode LoRa/Lte modems are stopped and have to be re-initialized after wakeup._
-
#### machine.deepsleep(\[time\_ms\])
Stops the CPU and all peripherals, including the networking interfaces (except for LTE). Execution is resumed from the main script, just as with a reset. If a value in milliseconds is given then the device will wake up after that period of time, otherwise it will remain in deep sleep until the reset button is pressed.
The products with LTE connectivity (FiPy, GPy, G01), require the LTE radio to be disabled separately via the LTE class before entering deepsleep. This is required due to the LTE radio being powered independently and allowing use cases which require the system to be taken out from deepsleep by an event from the LTE network (data or SMS received for instance).
-#### machine.pin\_sleep\_wakeup(pins, mode, enable\_pull)
+#### machine.pin\_deepsleep\_wakeup(pins, mode, enable\_pull)
-Configure pins to wake up from deep/light sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
+Configure pins to wake up from deep sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
The arguments are:
diff --git a/content/firmwareapi/pycom/machine/adc.md b/content/firmwareapi/pycom/machine/adc.md
index e3b168f..e81e1a8 100644
--- a/content/firmwareapi/pycom/machine/adc.md
+++ b/content/firmwareapi/pycom/machine/adc.md
@@ -6,13 +6,12 @@ aliases:
- chapter/firmwareapi/pycom/machine/adc
---
-# ADC
-
## class ADC – Analog to Digital Conversion
### Quick Usage Example
```python
+
import machine
adc = machine.ADC() # create an ADC object
@@ -48,6 +47,7 @@ Create an analog pin.
Returns an instance of `ADCChannel`. Example:
```python
+
# enable an ADC channel on P16
apin = adc.channel(pin='P16')
```
diff --git a/content/firmwareapi/pycom/machine/can.md b/content/firmwareapi/pycom/machine/can.md
index 81170a8..4c825a8 100644
--- a/content/firmwareapi/pycom/machine/can.md
+++ b/content/firmwareapi/pycom/machine/can.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/machine/can.md
- chapter/firmwareapi/pycom/machine/can
---
+
The CAN class supports the full CAN 2.0 specification with standard and extended frames, as well as acceptance filtering.
The ESP32 has a built-in CAN controller, but the transceiver needs to be added externally. A recommended device is the SN65HVD230.
@@ -12,6 +13,7 @@ The ESP32 has a built-in CAN controller, but the transceiver needs to be added e
## Quick Usage Example
```python
+
from machine import CAN
can = CAN(mode=CAN.NORMAL, baudrate=500000, pins=('P22', 'P23'))
@@ -26,6 +28,7 @@ can.recv()
Create an CAN object. See init for parameters of initialisation.:
```python
+
# only 1 CAN peripheral is available, so the bus must always be 0
can = CAN(0, mode=CAN.NORMAL, baudrate=500000, pins=('P22', 'P23')) # pin order is Tx, Rx
```
@@ -58,6 +61,7 @@ Send a CAN frame on the bus
Can be used like:
```python
+
can.send(id=0x0020, data=bytes([0x01, 0x02, 0x03, 0x04, 0x05]), extended=True) # sends 5 bytes with an extended identifier
can.send(id=0x010, data=bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])) # sends 8 bytes with an standard identifier
@@ -72,6 +76,7 @@ Get a message from the receive queue, and optionally specify a timeout value in
`(id, data, rtr, extended)`
```python
+
>>> can.recv()
(id=0x012, data=b'123', rtr=False, extended=False)
```
@@ -91,6 +96,7 @@ With software filters all messages in the bus are received by the CAN controller
For example:
```python
+
can.soft_filter(CAN.FILTER_LIST, [0x100, 0x200, 0x300, 0x400]) # only accept identifiers from 0x100, 0x200, 0x300 and 0x400
can.soft_filter(CAN.FILTER_RANGE, [(0x001, 0x010), (0x020, 0x030), (0x040, 0x050)]) # only accept identifiers from 0x001 to 0x010, from 0x020 to 0x030 and from 0x040 to 0x050.
@@ -117,6 +123,7 @@ The values can be OR-ed together, for instance `trigger=CAN.RX_FRAME | CAN.RX_FI
It can be used like this:
```python
+
from machine import CAN
can = CAN(mode=CAN.NORMAL, baudrate=500000, pins=('P22', 'P23'))
diff --git a/content/firmwareapi/pycom/machine/dac.md b/content/firmwareapi/pycom/machine/dac.md
index c23ae54..10058f7 100644
--- a/content/firmwareapi/pycom/machine/dac.md
+++ b/content/firmwareapi/pycom/machine/dac.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/dac.md
- chapter/firmwareapi/pycom/machine/dac
---
+
The DAC is used to output analog values (a specific voltage) on pin `P22` or pin `P21`. The voltage will be between `0` and `3.3V`.
## Quick Usage Example
```python
+
import machine
dac = machine.DAC('P22') # create a DAC object
diff --git a/content/firmwareapi/pycom/machine/i2c.md b/content/firmwareapi/pycom/machine/i2c.md
index a8c1355..d75dd1d 100644
--- a/content/firmwareapi/pycom/machine/i2c.md
+++ b/content/firmwareapi/pycom/machine/i2c.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/machine/i2c.md
- chapter/firmwareapi/pycom/machine/i2c
---
+
I2C is a two-wire protocol for communicating between devices. At the physical level it consists of 2 wires: SCL and SDA, the clock and data lines respectively.
I2C objects are created attached to a specific bus. They can be initialised when created, or initialised later on.
@@ -12,6 +13,7 @@ I2C objects are created attached to a specific bus. They can be initialised when
## Example using default Pins
```python
+
from machine import I2C
i2c = I2C(0) # create on bus 0
@@ -24,6 +26,7 @@ i2c.deinit() # turn off the peripheral
## Example using non-default Pins
```python
+
from machine import I2C
i2c = I2C(0, pins=('P10','P11')) # create and use non-default PIN assignments (P10=SDA, P11=SCL)
@@ -36,6 +39,7 @@ Printing the `i2c` object gives you information about its configuration.
A master must specify the recipient's address:
```python
+
i2c.init(I2C.MASTER)
i2c.writeto(0x42, '123') # send 3 bytes to slave with address 0x42
i2c.writeto(addr=0x42, b'456') # keyword for address
@@ -44,6 +48,7 @@ i2c.writeto(addr=0x42, b'456') # keyword for address
Master also has other methods:
```python
+
i2c.scan() # scan for slaves on the bus, returning
# a list of valid addresses
i2c.readfrom_mem(0x42, 2, 3) # read 3 bytes from memory of slave 0x42,
@@ -55,6 +60,7 @@ i2c.writeto_mem(0x42, 2, 'abc') # write 'abc' (3 bytes) to memory of slave 0
## Quick Usage Example
```python
+
from machine import I2C
# configure the I2C bus
i2c = I2C(0, I2C.MASTER, baudrate=100000)
diff --git a/content/firmwareapi/pycom/machine/pin.md b/content/firmwareapi/pycom/machine/pin.md
index 4b7319b..5657cca 100644
--- a/content/firmwareapi/pycom/machine/pin.md
+++ b/content/firmwareapi/pycom/machine/pin.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/pin.md
- chapter/firmwareapi/pycom/machine/pin
---
+
A pin is the basic object to control I/O pins (also known as GPIO - general-purpose input/output). It has methods to set the mode of the pin (input, output, etc) and methods to get and set the digital logic level. For analog control of a pin, see the ADC class.
## Quick Usage Example
```python
+
from machine import Pin
# initialize `P9` in gpio mode and make it an output
@@ -31,6 +33,7 @@ p_in() # get value, 0 or 1
Create a new Pin object associated with the string `id`. If additional arguments are given, they are used to initialise the pin. [See pin.init()](../pin#pin-init-mode-pull-alt)
```python
+
from machine import Pin
p = Pin('P10', mode=Pin.OUT, pull=None, alt=-1)
```
@@ -49,6 +52,8 @@ Initialise the pin:
* `None` - no pull up or down resistor.
* `Pin.PULL_UP` - pull up resistor enabled.
* `Pin.PULL_DOWN` - pull down resistor enabled.
+* `*`
+ * Pin value: `0` or `1`
* `alt` is the id of the alternate function.
Returns: `None`.
@@ -71,6 +76,7 @@ Pin objects are callable. The call method provides a (fast) shortcut to set and
Example:
```python
+
from machine import Pin
pin = Pin('P12', mode=Pin.IN, pull=Pin.PULL_UP)
pin() # fast method to get the value
@@ -114,6 +120,7 @@ The values can be OR-ed together, for instance `trigger=Pin.IRQ_FALLING | Pin.IR
Example:
```python
+
from machine import Pin
def pin_handler(arg):
@@ -124,7 +131,7 @@ p_in.callback(Pin.IRQ_FALLING | Pin.IRQ_RISING, pin_handler)
```
{{% hint style="info" %}}
-For more information on how Pycom's products handle interrupts, see [here](../../../notes.md#interrupt-handling).
+For more information on how Pycom's products handle interrupts, see [here](/firmwareapi/notes#interrupt-handling).
{{< /hint >}}
## Attributes
@@ -134,6 +141,7 @@ For more information on how Pycom's products handle interrupts, see [here](../..
Contains all Pin objects supported by the expansion board. Examples:
```python
+
Pin.exp_board.G16
led = Pin(Pin.exp_board.G16, mode=Pin.OUT)
Pin.exp_board.G16.id()
@@ -144,6 +152,7 @@ Pin.exp_board.G16.id()
Contains all `Pin` objects supported by the module. Examples:
```python
+
Pin.module.P9
led = Pin(Pin.module.P9, mode=Pin.OUT)
Pin.module.P9.id()
diff --git a/content/firmwareapi/pycom/machine/pwm.md b/content/firmwareapi/pycom/machine/pwm.md
index 5b60220..fb3148e 100644
--- a/content/firmwareapi/pycom/machine/pwm.md
+++ b/content/firmwareapi/pycom/machine/pwm.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/pwm.md
- chapter/firmwareapi/pycom/machine/pwm
---
+
## class PWM – Pulse Width Modulation
### Quick Usage Example
```python
+
from machine import PWM
pwm = PWM(0, frequency=5000) # use PWM timer 0, with a frequency of 5KHz
# create pwm channel on pin P12 with a duty cycle of 50%
diff --git a/content/firmwareapi/pycom/machine/rmt.md b/content/firmwareapi/pycom/machine/rmt.md
index e93b6a8..54a3298 100644
--- a/content/firmwareapi/pycom/machine/rmt.md
+++ b/content/firmwareapi/pycom/machine/rmt.md
@@ -11,6 +11,7 @@ The RMT (Remote Control) module is primarily designed to send and receive infrar
## Quick Usage Example: sending
```python
+
import machine
# create a RMT object for transmission
@@ -26,6 +27,7 @@ rmt.send_pulses(duration, data)
## Quick Usage Example: receiving
```python
+
import machine
# create a RMT object
rmt = machine.RMT(channel=3)
@@ -107,19 +109,23 @@ Return value: Tuple of items with the following structure: `(level, duration)`:
Maximum of 128 pulses can be received in a row without receiving "idle" signal. If the incoming pulse sequence contains more than 128 pulses the rest is dropped and the receiver waits for another sequence of pulses. The `pulses_get` function can be called to receive more than 128 pulses, however the above mentioned limitation should be kept in mind when evaluating the received data.
{{< /hint >}}
-#### rmt.pulses\_send(duration, data, start\_level, wait\_tx\_done)
+#### rmt.pulses\_send(duration, data, start\_level)
Generates pulses as defined by the parameters below
-* `duration` represents the duration of the pulses to be sent, the time unit (resolution) depends on the selected channel.
-* `data` Tuple that represents the sequence of pulses to be sent, must be composed of 0 or 1 elements.
-* `start_level` defines the state (HIGH/LOW) of the first pulse given by `duration` if `data` is not given.
-* `data` must be a tuple and `duration` can be a tuple or a single number, with `data` being optional. In the case that only `duration` is provided, it must be a tuple and you must also provide `start_level` which will dictate the level of the first duration, the signal level then toggles between each duration value.
- * If `data` is provided and `duration` is a single number, each pulse in `data` will have have an equal length as set by `duration`.
- * If `data` and `duration` are provided as tuples, they must be of the same number of elements, with each pulse lasting its matching duration.
-* `wait_tx_done` :
- * `False`: Allows the function to send asynchronosly without waiting for the transmission to be done.
- * `True`: will wait for transmission to be done
+* `duration` represents the duration of the pulses to be sent,
+
+ the time unit (resolution) depends on the selected channel.
+
+* `data` Tuple that represents the sequence of pulses to be sent, must be
+
+ composed of 0 or 1 elements.
+
+* `start_level` defines the state (HIGH/LOW) of the first pulse given by
+
+ `duration` if `data` is not given.
+
+`data` must be a tuple and `duration` can be a tuple or a single number, with `data` being optional. In the case that only `duration` is provided, it must be a tuple and you must also provide `start_level` which will dictate the level of the first duration, the signal level then toggles between each duration value. If `data` is provided and `duration` is a single number, each pulse in `data` will have have an equal length as set by `duration`. If `data` and `duration` are provided as tuples, they must be of the same number of elements, with each pulse lasting its matching duration.
## Constants
diff --git a/content/firmwareapi/pycom/machine/rtc.md b/content/firmwareapi/pycom/machine/rtc.md
index f3d46aa..a53b8f1 100644
--- a/content/firmwareapi/pycom/machine/rtc.md
+++ b/content/firmwareapi/pycom/machine/rtc.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/rtc.md
- chapter/firmwareapi/pycom/machine/rtc
---
+
The RTC is used to keep track of the date and time.
## Quick Usage Example
```python
+
from machine import RTC
rtc = RTC()
@@ -24,6 +26,7 @@ print(rtc.now())
Create an RTC object. See init for parameters of initialisation.
```python
+
# id of the RTC may be set if multiple are connected. Defaults to id = 0.
rtc = RTC(id=0)
```
@@ -34,12 +37,13 @@ rtc = RTC(id=0)
Initialise the RTC. The arguments are:
-* `datetime` when passed it sets the current time. It is a tuple of the form: `(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])`.
+* `datetime` when passed it sets the current time. It is a tuple of the form: `(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])`
* `source` selects the oscillator that drives the RTC. The options are RTC.INTERNAL\_RC and RTC.XTAL\_32KHZ
For example:
```python
+
# for 2nd of February 2017 at 10:30am (TZ 0)
rtc.init((2017, 2, 28, 10, 30, 0, 0, 0))
```
@@ -53,6 +57,7 @@ rtc.init((2017, 2, 28, 10, 30, 0, 0, 0))
Get get the current `datetime` tuple:
```python
+
# returns datetime tuple
rtc.now()
```
@@ -67,6 +72,7 @@ Set up automatic fetch and update the time using NTP (SNTP).
Can be used like:
```python
+
rtc.ntp_sync("pool.ntp.org") # this is an example. You can select a more specific server according to your geographical location
```
@@ -75,27 +81,10 @@ rtc.ntp_sync("pool.ntp.org") # this is an example. You can select a more specifi
Returns `True` if the last `ntp_sync` has been completed, `False` otherwise:
```python
+
rtc.synced()
```
-#### rtc.memory(\[data\])
-
-Reads RTC memory contents or write data in passed Buffer in to RTC memory
-
-Example:
-
-```python
-rtc = RTC()
-rtc.memory(b'10101010') # writes data in RTC memory
-rtc.memory()
-```
-
-Output:
-
-```python
-b'10101010'
-```
-
## Constants
* Clock source: `RTC.INTERNAL_RC`, `RTC.XTAL_32KHZ`
diff --git a/content/firmwareapi/pycom/machine/sd.md b/content/firmwareapi/pycom/machine/sd.md
index 3e877b9..2f524e2 100644
--- a/content/firmwareapi/pycom/machine/sd.md
+++ b/content/firmwareapi/pycom/machine/sd.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/machine/sd.md
- chapter/firmwareapi/pycom/machine/sd
---
+
The SD card class allows to configure and enable the memory card module of your Pycom module and automatically mount it as `/sd` as part of the file system. There is a single pin combination that can be used for the SD card, and the current implementation only works in 1-bit mode. The pin connections are as follows:
`P8: DAT0`, `P23: SCLK` and `P4: CMD` (no external pull-up resistors are needed)
@@ -18,6 +19,7 @@ Make sure your SD card is formatted either as FAT16 or FAT32.
## Quick Example Usage:
```python
+
from machine import SD
import os
diff --git a/content/firmwareapi/pycom/machine/spi.md b/content/firmwareapi/pycom/machine/spi.md
index bdec246..6576c34 100644
--- a/content/firmwareapi/pycom/machine/spi.md
+++ b/content/firmwareapi/pycom/machine/spi.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/spi.md
- chapter/firmwareapi/pycom/machine/spi
---
+
SPI is a serial protocol that is driven by a master. At the physical level there are 3 lines: SCK, MOSI, MISO.
See usage model of I2C; SPI is very similar. Main difference is parameters to init the SPI bus:
```python
+
from machine import SPI
spi = SPI(0, mode=SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.MSB)
```
@@ -19,6 +21,7 @@ Only required parameter is mode, must be SPI.MASTER. Polarity can be 0 or 1, and
## Quick Usage Example
```python
+
from machine import SPI
# configure the SPI master @ 2MHz
@@ -33,6 +36,7 @@ spi.write_readinto(bytes([0x01, 0x02, 0x03, 0x04, 0x05]), rbuf) # send a receive
## Quick Usage Example using non-default pins
```python
+
from machine import SPI
# configure the SPI master @ 2MHz
diff --git a/content/firmwareapi/pycom/machine/timer.md b/content/firmwareapi/pycom/machine/timer.md
index da52306..7ceefbb 100644
--- a/content/firmwareapi/pycom/machine/timer.md
+++ b/content/firmwareapi/pycom/machine/timer.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/machine/timer.md
- chapter/firmwareapi/pycom/machine/timer
---
+
## class Timer – Measure Time and Set Alarms
Timers can be used for a great variety of tasks, like measuring time spans or being notified that a specific interval has elapsed.
@@ -71,6 +72,7 @@ Get the elapsed time in microseconds.
Example:
```python
+
from machine import Timer
import time
@@ -109,6 +111,7 @@ Disables the alarm.
Example:
```python
+
from machine import Timer
class Clock:
@@ -127,5 +130,5 @@ clock = Clock()
```
{{% hint style="info" %}}
-For more information on how Pycom's products handle interrupts, see [notes](../../../notes.md#interrupt-handling).
+For more information on how Pycom's products handle interrupts, see [notes](/firmwareapi/notes#interrupt-handling).
{{< /hint >}}
diff --git a/content/firmwareapi/pycom/machine/uart.md b/content/firmwareapi/pycom/machine/uart.md
index 5312f3e..a7fd3cb 100644
--- a/content/firmwareapi/pycom/machine/uart.md
+++ b/content/firmwareapi/pycom/machine/uart.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/uart.md
- chapter/firmwareapi/pycom/machine/uart
---
+
UART implements the standard UART/USART duplex serial communications protocol. At the physical level it consists of 2 lines: RXD and TXD. The unit of communication is a character (not to be confused with a string character) which can be 5, 6, 7 or 8 bits wide.
UART objects can be created and initialised using:
```python
+
from machine import UART
uart = UART(1, 9600) # init with given baudrate
@@ -21,6 +23,7 @@ Bits can be `5, 6, 7, 8`. Parity can be `None`, `UART.EVEN` or `UART.ODD`. Stop
A UART object acts like a stream object therefore reading and writing is done using the standard stream methods:
```python
+
uart.read(10) # read 10 characters, returns a bytes object
uart.readall() # read all available characters
uart.readline() # read a line
@@ -31,12 +34,14 @@ uart.write('abc') # write the 3 characters
To check if there is anything to be read, use:
```python
+
uart.any() # returns the number of characters available for reading
```
## Quick Usage Example
```python
+
from machine import UART
# this uses the UART_1 default pins for TXD and RXD (``P3`` and ``P4``)
uart = UART(1, baudrate=9600)
@@ -47,6 +52,7 @@ uart.read(5) # read up to 5 bytes
## Quick Usage Example using non-default pins (TXD/RXD only)
```python
+
from machine import UART
# this uses the UART_1 non-default pins for TXD and RXD (``P20`` and ``P21``)
uart = UART(1, baudrate=9600, pins=('P20','P21'))
@@ -57,6 +63,7 @@ uart.read(5) # read up to 5 bytes
## Quick Usage Example using non-default pins (TXD/RXD and flow control)
```python
+
from machine import UART
# this uses the UART_1 non-default pins for TXD, RXD, RTS and CTS (``P20``, ``P21``, ``P22``and ``P23``)
uart = UART(1, baudrate=9600, pins=('P20', 'P21', 'P22', 'P23'))
diff --git a/content/firmwareapi/pycom/machine/wdt.md b/content/firmwareapi/pycom/machine/wdt.md
index 258e5f3..a87ea39 100644
--- a/content/firmwareapi/pycom/machine/wdt.md
+++ b/content/firmwareapi/pycom/machine/wdt.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/machine/wdt.md
- chapter/firmwareapi/pycom/machine/wdt
---
+
The WDT is used to restart the system when the application crashes and ends up into a non recoverable state. After enabling, the application must "feed" the watchdog periodically to prevent it from expiring and resetting the system.
## Quick Usage Example
```python
+
from machine import WDT
wdt = WDT(timeout=2000) # enable it with a timeout of 2 seconds
wdt.feed()
diff --git a/content/firmwareapi/pycom/network/README.md b/content/firmwareapi/pycom/network/README.md
index af729fd..8d6f7a1 100644
--- a/content/firmwareapi/pycom/network/README.md
+++ b/content/firmwareapi/pycom/network/README.md
@@ -3,5 +3,6 @@ title: "network"
aliases:
- chapter/firmwareapi/pycom/network
---
+
This module provides access to network drivers and routing configuration. Network drivers for specific hardware are available within this module and are used to configure specific hardware network interfaces.
diff --git a/content/firmwareapi/pycom/network/_index.md b/content/firmwareapi/pycom/network/_index.md
index 1796767..3eacd72 100644
--- a/content/firmwareapi/pycom/network/_index.md
+++ b/content/firmwareapi/pycom/network/_index.md
@@ -2,5 +2,6 @@
title: "network"
aliases:
---
+
This module provides access to network drivers and routing configuration. Network drivers for specific hardware are available within this module and are used to configure specific hardware network interfaces.
diff --git a/content/firmwareapi/pycom/network/bluetooth/README.md b/content/firmwareapi/pycom/network/bluetooth/README.md
index 8bf46e0..41d5111 100644
--- a/content/firmwareapi/pycom/network/bluetooth/README.md
+++ b/content/firmwareapi/pycom/network/bluetooth/README.md
@@ -3,11 +3,17 @@ title: "Bluetooth"
aliases:
- chapter/firmwareapi/pycom/network/bluetooth
---
+search: false
+---
+
+# Bluetooth
+
This class provides a driver for the Bluetooth radio in the module. Currently, only basic BLE functionality is available.
## Quick Usage Example
```python
+
from network import Bluetooth
import time
bt = Bluetooth()
@@ -46,40 +52,44 @@ GAP allows for devices to take various roles but generic flow works with devices
## Constructors
-#### class network.Bluetooth(id=0, ...)
+### class network.Bluetooth(id=0, ...)
Create a Bluetooth object, and optionally configure it. See init for params of configuration.
Example:
```python
+
from network import Bluetooth
bluetooth = Bluetooth()
```
## Methods
-#### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None)
+### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None)
* `id` Only one Bluetooth peripheral available so must always be 0
* `mode` currently the only supported mode is `Bluetooth.BLE`
-* `antenna` selects between the internal and the external antenna. Can be either
+* `antenna` selects between the internal and the external antenna. Can be either`Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`.
- `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`.
-
- With our development boards it defaults to using the internal antenna, but in
-
- the case of an OEM module, the antenna pin (`P12`) is not used, so it's free to be
-
- used for other things.
+ With our development boards it defaults to using the internal antenna, but in the case of an OEM module, the antenna pin (`P12`) is not used, so it's free to be used for other things.
Initialises and enables the Bluetooth radio in BLE mode.
-#### bluetooth.deinit()
+{{% hint style="info" %}}
+To use an external antenna, set `P12 as output pin.`
+
+```python
+
+Pin('P12', mode=Pin.OUT)(True)
+```
+{{< /hint >}}
+
+### bluetooth.deinit()
Disables the Bluetooth radio.
-#### bluetooth.start\_scan(timeout)
+### bluetooth.start\_scan(timeout)
Starts performing a scan listening for BLE devices sending advertisements. This function always returns immediately, the scanning will be performed on the background. The return value is `None`. After starting the scan the function `get_adv()` can be used to retrieve the advertisements messages from the FIFO. The internal FIFO has space to cache 16 advertisements.
@@ -90,19 +100,20 @@ The arguments are:
Examples:
```python
+
bluetooth.start_scan(10) # starts scanning and stop after 10 seconds
bluetooth.start_scan(-1) # starts scanning indefinitely until bluetooth.stop_scan() is called
```
-#### bluetooth.stop\_scan()
+### bluetooth.stop\_scan()
Stops an ongoing scanning process. Returns `None`.
-#### bluetooth.isscanning()
+### bluetooth.isscanning()
Returns `True` if a Bluetooth scan is in progress. `False` otherwise.
-#### bluetooth.get\_adv()
+### bluetooth.get\_adv()
Gets an named tuple with the advertisement data received during the scanning. The tuple has the following structure: `(mac, addr_type, adv_type, rssi, data)`
@@ -115,6 +126,7 @@ Gets an named tuple with the advertisement data received during the scanning. Th
Example for getting `mac` address of an advertiser:
```python
+
import ubinascii
bluetooth = Bluetooth()
@@ -124,11 +136,11 @@ adv = bluetooth.get_adv() #
ubinascii.hexlify(adv.mac) # convert hexadecimal to ascii
```
-#### bluetooth.get\_advertisements()
+### bluetooth.get\_advertisements()
Same as the `get_adv()` method, but this one returns a list with all the advertisements received.
-#### bluetooth.resolve\_adv\_data(data, data\_type)
+### bluetooth.resolve\_adv\_data(data, data\_type)
Parses the advertisement data and returns the requested `data_type` if present. If the data type is not present, the function returns `None`.
@@ -140,6 +152,7 @@ Arguments:
Example:
```python
+
import ubinascii
from network import Bluetooth
bluetooth = Bluetooth()
@@ -158,16 +171,18 @@ while bluetooth.isscanning():
print(ubinascii.hexlify(mfg_data))
```
-#### bluetooth.connect(mac\_addr, timeout=None)
+### bluetooth.connect(mac\_addr)
-* `mac_addr` is the address of the remote device to connect
-* `timeout` specifies the amount of time in milliseconds to wait for the connection process to finish. If not given then no timeout is applied The function blocks until the connection succeeds or fails (raises OSError) or the given `timeout` expires (raises `Bluetooth.timeout TimeoutError`). If the connections succeeds it returns a object of type `GATTCConnection`.
+Opens a BLE connection with the device specified by the `mac_addr` argument. This function blocks until the connection succeeds or fails. If the connections succeeds it returns a object of type `GATTCConnection`.
+
+Connections are initiated by the central device. There is a maximum of 4 simultaneous connections.
```python
+
bluetooth.connect('112233eeddff') # mac address is accepted as a string
```
-#### bluetooth.callback(trigger=None, handler=None, arg=None)
+### bluetooth.callback(trigger=None, handler=None, arg=None)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
@@ -177,13 +192,14 @@ Creates a callback that will be executed when any of the triggers occurs. The ar
An example of how this may be used can be seen in the [`bluetooth.events()`](./#bluetooth-events) method.
-#### bluetooth.events()
+### bluetooth.events()
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
Example of usage:
```python
+
from network import Bluetooth
bluetooth = Bluetooth()
@@ -201,7 +217,7 @@ bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONN
bluetooth.advertise(True)
```
-#### bluetooth.set\_advertisement(\* , name=None, manufacturer\_data=None, service\_data=None, service\_uuid=None)
+### bluetooth.set\_advertisement(\* , name=None, manufacturer\_data=None, service\_data=None, service\_uuid=None)
Configure the data to be sent while advertising. If left with the default of `None` the data won't be part of the advertisement message.
@@ -215,14 +231,15 @@ The arguments are:
Example:
```python
+
bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")
```
-#### bluetooth.advertise(\[Enable\])
+### bluetooth.advertise(\[Enable\])
Start or stop sending advertisements. The `set_advertisement()` method must have been called prior to this one.
-#### bluetooth.service(uuid, \* , isprimary=True, nbr\_chars=1, start=True)
+### bluetooth.service(uuid, \* , isprimary=True, nbr\_chars=1, start=True)
Create a new service on the internal GATT server. Returns a object of type `BluetoothServerService`.
@@ -234,10 +251,11 @@ The arguments are:
* `start` if `True` the service is started immediately.
```python
+
bluetooth.service('abc123')
```
-#### bluetooth.disconnect\_client()
+### bluetooth.disconnect\_client()
Closes the BLE connection with the client.
@@ -251,7 +269,3 @@ Closes the BLE connection with the client.
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`
-## Exceptions
-
-* `Bluetooth.timeout`
-
diff --git a/content/firmwareapi/pycom/network/bluetooth/_index.md b/content/firmwareapi/pycom/network/bluetooth/_index.md
index a7508cf..ccacc09 100644
--- a/content/firmwareapi/pycom/network/bluetooth/_index.md
+++ b/content/firmwareapi/pycom/network/bluetooth/_index.md
@@ -2,6 +2,7 @@
title: "Bluetooth"
aliases:
---
+
This class provides a driver for the Bluetooth radio in the module. Currently, only basic BLE functionality is available.
## Quick Usage Example
@@ -45,40 +46,44 @@ GAP allows for devices to take various roles but generic flow works with devices
## Constructors
-#### class network.Bluetooth(id=0, ...)
+### class network.Bluetooth(id=0, ...)
Create a Bluetooth object, and optionally configure it. See init for params of configuration.
Example:
```python
+
from network import Bluetooth
bluetooth = Bluetooth()
```
## Methods
-#### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None)
+### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None)
* `id` Only one Bluetooth peripheral available so must always be 0
* `mode` currently the only supported mode is `Bluetooth.BLE`
-* `antenna` selects between the internal and the external antenna. Can be either
+* `antenna` selects between the internal and the external antenna. Can be either`Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`.
- `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`.
-
- With our development boards it defaults to using the internal antenna, but in
-
- the case of an OEM module, the antenna pin (`P12`) is not used, so it's free to be
-
- used for other things.
+ With our development boards it defaults to using the internal antenna, but in the case of an OEM module, the antenna pin (`P12`) is not used, so it's free to be used for other things.
Initialises and enables the Bluetooth radio in BLE mode.
-#### bluetooth.deinit()
+{{% hint style="info" %}}
+To use an external antenna, set `P12 as output pin.`
+
+```python
+
+Pin('P12', mode=Pin.OUT)(True)
+```
+{{< /hint >}}
+
+### bluetooth.deinit()
Disables the Bluetooth radio.
-#### bluetooth.start\_scan(timeout)
+### bluetooth.start\_scan(timeout)
Starts performing a scan listening for BLE devices sending advertisements. This function always returns immediately, the scanning will be performed on the background. The return value is `None`. After starting the scan the function `get_adv()` can be used to retrieve the advertisements messages from the FIFO. The internal FIFO has space to cache 16 advertisements.
@@ -89,19 +94,20 @@ The arguments are:
Examples:
```python
+
bluetooth.start_scan(10) # starts scanning and stop after 10 seconds
bluetooth.start_scan(-1) # starts scanning indefinitely until bluetooth.stop_scan() is called
```
-#### bluetooth.stop\_scan()
+### bluetooth.stop\_scan()
Stops an ongoing scanning process. Returns `None`.
-#### bluetooth.isscanning()
+### bluetooth.isscanning()
Returns `True` if a Bluetooth scan is in progress. `False` otherwise.
-#### bluetooth.get\_adv()
+### bluetooth.get\_adv()
Gets an named tuple with the advertisement data received during the scanning. The tuple has the following structure: `(mac, addr_type, adv_type, rssi, data)`
@@ -114,6 +120,7 @@ Gets an named tuple with the advertisement data received during the scanning. Th
Example for getting `mac` address of an advertiser:
```python
+
import ubinascii
bluetooth = Bluetooth()
@@ -123,11 +130,11 @@ adv = bluetooth.get_adv() #
ubinascii.hexlify(adv.mac) # convert hexadecimal to ascii
```
-#### bluetooth.get\_advertisements()
+### bluetooth.get\_advertisements()
Same as the `get_adv()` method, but this one returns a list with all the advertisements received.
-#### bluetooth.resolve\_adv\_data(data, data\_type)
+### bluetooth.resolve\_adv\_data(data, data\_type)
Parses the advertisement data and returns the requested `data_type` if present. If the data type is not present, the function returns `None`.
@@ -139,6 +146,7 @@ Arguments:
Example:
```python
+
import ubinascii
from network import Bluetooth
bluetooth = Bluetooth()
@@ -157,16 +165,18 @@ while bluetooth.isscanning():
print(ubinascii.hexlify(mfg_data))
```
-#### bluetooth.connect(mac\_addr, timeout=None)
+### bluetooth.connect(mac\_addr)
-* `mac_addr` is the address of the remote device to connect
-* `timeout` specifies the amount of time in milliseconds to wait for the connection process to finish. If not given then no timeout is applied The function blocks until the connection succeeds or fails (raises OSError) or the given `timeout` expires (raises `Bluetooth.timeout TimeoutError`). If the connections succeeds it returns a object of type `GATTCConnection`.
+Opens a BLE connection with the device specified by the `mac_addr` argument. This function blocks until the connection succeeds or fails. If the connections succeeds it returns a object of type `GATTCConnection`.
+
+Connections are initiated by the central device. There is a maximum of 4 simultaneous connections.
```python
+
bluetooth.connect('112233eeddff') # mac address is accepted as a string
```
-#### bluetooth.callback(trigger=None, handler=None, arg=None)
+### bluetooth.callback(trigger=None, handler=None, arg=None)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
@@ -176,13 +186,14 @@ Creates a callback that will be executed when any of the triggers occurs. The ar
An example of how this may be used can be seen in the [`bluetooth.events()`](./#bluetooth-events) method.
-#### bluetooth.events()
+### bluetooth.events()
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
Example of usage:
```python
+
from network import Bluetooth
bluetooth = Bluetooth()
@@ -200,7 +211,7 @@ bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONN
bluetooth.advertise(True)
```
-#### bluetooth.set\_advertisement(\* , name=None, manufacturer\_data=None, service\_data=None, service\_uuid=None)
+### bluetooth.set\_advertisement(\* , name=None, manufacturer\_data=None, service\_data=None, service\_uuid=None)
Configure the data to be sent while advertising. If left with the default of `None` the data won't be part of the advertisement message.
@@ -214,14 +225,15 @@ The arguments are:
Example:
```python
+
bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")
```
-#### bluetooth.advertise(\[Enable\])
+### bluetooth.advertise(\[Enable\])
Start or stop sending advertisements. The `set_advertisement()` method must have been called prior to this one.
-#### bluetooth.service(uuid, \* , isprimary=True, nbr\_chars=1, start=True)
+### bluetooth.service(uuid, \* , isprimary=True, nbr\_chars=1, start=True)
Create a new service on the internal GATT server. Returns a object of type `BluetoothServerService`.
@@ -233,10 +245,11 @@ The arguments are:
* `start` if `True` the service is started immediately.
```python
+
bluetooth.service('abc123')
```
-#### bluetooth.disconnect\_client()
+### bluetooth.disconnect\_client()
Closes the BLE connection with the client.
@@ -249,8 +262,3 @@ Closes the BLE connection with the client.
* Characteristic properties (bit values that can be combined): `Bluetooth.PROP_BROADCAST`, `Bluetooth.PROP_READ`, `Bluetooth.PROP_WRITE_NR`, `Bluetooth.PROP_WRITE`, `Bluetooth.PROP_NOTIFY`, `Bluetooth.PROP_INDICATE`, `Bluetooth.PROP_AUTH`, `Bluetooth.PROP_EXT_PROP`
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`
-
-## Exceptions
-
-* `Bluetooth.timeout`
-
diff --git a/content/firmwareapi/pycom/network/bluetooth/gatt.md b/content/firmwareapi/pycom/network/bluetooth/gatt.md
index 1262363..75d2564 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gatt.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gatt.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gatt.md
- chapter/firmwareapi/pycom/network/bluetooth/gatt
---
+
GATT stands for the Generic Attribute Profile and it defines the way that two Bluetooth Low Energy devices communicate between each other using concepts called Services and Characteristics. GATT uses a data protocol known as the Attribute Protocol (ATT), which is used to store/manage Services, Characteristics and related data in a lookup table.
GATT comes into use once a connection is established between two devices, meaning that the device will have already gone through the advertising process managed by GAP. It's important to remember that this connection is exclusive; i.e. that only one client is connected to one server at a time. This means that the client will stop advertising once a connection has been made. This remains the case, until the connection is broken or disconnected.
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md b/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
index 5a855a1..9eef49c 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
@@ -4,6 +4,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gattccharacteristic.html
- firmwareapi/pycom/network/bluetooth/gattccharacteristic.md
---
+
The smallest concept in GATT is the Characteristic, which encapsulates a single data point (though it may contain an array of related data, such as X/Y/Z values from a 3-axis accelerometer, longitude and latitude from a GPS, etc.).
The following class allows you to manage characteristics from a Client.
@@ -35,6 +36,7 @@ Returns the locally stored value of the characteristic without sending a read re
Writes the given value on the characteristic. For now it only accepts bytes object representing the value to be written.
```python
+
characteristic.write(b'x0f')
```
@@ -46,25 +48,3 @@ This method allows to register for notifications on the characteristic.
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given, the characteristic object that owns the callback will be used.
-#### characteristic.read\_descriptor(uuid)
-
-Returns the value of the descriptor specified by the `uuid` parameter. If no descriptor found for the characteristic returns None.
-
-```python
-descriptor = char.read_descriptor(0x2900)
-if(descriptor != None):
- print("Characteristic Extended Properties: " + str(binascii.hexlify((descriptor))))
-
-descriptor = char.read_descriptor(0x2901)
-if(descriptor != None):
- print("Characteristic User Description: " + str(binascii.hexlify((descriptor))))
-
-descriptor = char.read_descriptor(0x2902)
-if(descriptor != None):
- print("Client Characteristic Configuration: " + str(binascii.hexlify((descriptor))))
-
-descriptor = char.read_descriptor(0x2904)
-if(descriptor != None):
- print("Characteristic Presentation Format: " + str(binascii.hexlify((descriptor))))
-```
-
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattcconnection.md b/content/firmwareapi/pycom/network/bluetooth/gattcconnection.md
index 8468e42..4d920a5 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattcconnection.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattcconnection.md
@@ -4,6 +4,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gattcconnection.html
- firmwareapi/pycom/network/bluetooth/gattcconnection.md
---
+
The GATT Client is the device that requests data from the server, otherwise known as the master device (commonly this might be a phone/tablet/PC). All transactions are initiated by the master, which receives a response from the slave.
## Methods
@@ -19,6 +20,7 @@ Returns `True` if the connection is still open. `False` otherwise.
Example:
```python
+
from network import Bluetooth
import ubinascii
bluetooth = Bluetooth()
@@ -46,6 +48,7 @@ Performs a service search on the connected BLE peripheral (server) a returns a l
Example:
```python
+
# assuming that a BLE connection is already open
services = connection.services()
print(services)
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattccservice.md b/content/firmwareapi/pycom/network/bluetooth/gattccservice.md
index 2eda1d7..1d0f6f1 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattccservice.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattccservice.md
@@ -4,6 +4,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gattccservice.html
- firmwareapi/pycom/network/bluetooth/gattccservice.md
---
+
Services are used to categorise data up into specific chunks of data known as characteristics. A service may have multiple characteristics, and each service has a unique numeric ID called a UUID.
The following class allows control over Client services.
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattscharacteristic.md b/content/firmwareapi/pycom/network/bluetooth/gattscharacteristic.md
index 57c3f8c..4695f3c 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattscharacteristic.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattscharacteristic.md
@@ -4,6 +4,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gattscharacteristic.html
- firmwareapi/pycom/network/bluetooth/gattscharacteristic.md
---
+
The smallest concept in GATT is the Characteristic, which encapsulates a single data point (though it may contain an array of related data, such as X/Y/Z values from a 3-axis accelerometer, longitude and latitude from a GPS, etc.).
The following class allows you to manage Server characteristics.
@@ -15,6 +16,7 @@ The following class allows you to manage Server characteristics.
Gets or sets the value of the characteristic. Can take an integer, a string or a bytes object.
```python
+
characteristic.value(123) # set characteristic value to an integer with the value 123
characteristic.value() # get characteristic value
```
@@ -36,6 +38,7 @@ Returns a value with bit flags identifying the events that have occurred since t
An example of advertising and creating services on the device:
```python
+
from network import Bluetooth
bluetooth = Bluetooth()
diff --git a/content/firmwareapi/pycom/network/bluetooth/gattsservice.md b/content/firmwareapi/pycom/network/bluetooth/gattsservice.md
index a90095f..b277c8c 100644
--- a/content/firmwareapi/pycom/network/bluetooth/gattsservice.md
+++ b/content/firmwareapi/pycom/network/bluetooth/gattsservice.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/network/bluetooth/gattsservice.md
- chapter/firmwareapi/pycom/network/bluetooth/gattsservice
---
+
The GATT Server allows the device to act as a peripheral and hold its own ATT lookup data, server & characteristic definitions. In this mode, the device acts as a slave and a master must initiate a request.
Services are used to categorise data up into specific chunks of data known as characteristics. A service may have multiple characteristics, and each service has a unique numeric ID called a UUID.
@@ -31,6 +32,7 @@ Creates a new characteristic on the service. Returns an object of the class `GAT
* `value` sets the initial value. Can take an integer, a string or a bytes object.
```python
+
service.characteristic('temp', value=25)
```
diff --git a/content/firmwareapi/pycom/network/lora.md b/content/firmwareapi/pycom/network/lora.md
new file mode 100644
index 0000000..a920745
--- /dev/null
+++ b/content/firmwareapi/pycom/network/lora.md
@@ -0,0 +1,523 @@
+---
+title: "LoRa"
+aliases:
+ - firmwareapi/pycom/network/lora.html
+ - firmwareapi/pycom/network/lora.md
+ - chapter/firmwareapi/pycom/network/lora
+---
+
+This class provides a LoRaWAN 1.0.2 compliant driver for the LoRa network processor in the LoPy and FiPy. Below is an example demonstrating LoRaWAN Activation by Personalisation usage:
+
+```python
+
+from network import LoRa
+import socket
+import ubinascii
+import struct
+
+# Initialise LoRa in LORAWAN mode.
+# Please pick the region that matches where you are using the device:
+# Asia = LoRa.AS923
+# Australia = LoRa.AU915
+# Europe = LoRa.EU868
+# United States = LoRa.US915
+lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
+
+# create an ABP authentication params
+dev_addr = struct.unpack(">l", binascii.unhexlify('00000005'))[0]
+nwk_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
+app_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
+
+# join a network using ABP (Activation By Personalisation)
+lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
+
+# create a LoRa socket
+s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
+
+# set the LoRaWAN data rate
+s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
+
+# make the socket non-blocking
+s.setblocking(False)
+
+# send some data
+s.send(bytes([0x01, 0x02, 0x03]))
+
+# get any data received...
+data = s.recv(64)
+print(data)
+```
+
+{{% hint style="danger" %}}
+Please ensure that there is an antenna connected to your device before sending/receiving LoRa messages as improper use (e.g. without an antenna), may damage the device.
+{{< /hint >}}
+
+## Additional Examples
+
+For various other complete LoRa examples, check here for additional examples.
+
+## Constructors
+
+#### class network.LoRa(id=0, ...)
+
+Create and configure a LoRa object. See init for params of configuration.
+
+```python
+
+lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
+```
+
+## Methods
+
+#### lora.init(mode, \* ,region=LoRa.EU868, frequency=868000000, tx\_power=14, bandwidth=LoRa.BW\_125KHZ, sf=7, preamble=8, coding\_rate=LoRa.CODING\_4\_5, power\_mode=LoRa.ALWAYS\_ON, tx\_iq=False, rx\_iq=False, adr=False, public=True, tx\_retries=1, device\_class=LoRa.CLASS\_A)
+
+This method is used to set the LoRa subsystem configuration and to specific raw LoRa or LoRaWAN.
+
+The arguments are:
+
+* `mode` can be either `LoRa.LORA` or `LoRa.LORAWAN`.
+* `region` can take the following values: `LoRa.AS923`, `LoRa.AU915`, `LoRa.EU868` or `LoRa.US915`. If not provided this will default to `LoRaEU868`. If they are not specified, this will also set appropriate defaults for `frequency` and `tx_power`.
+* `frequency` accepts values between `863000000` and `870000000` in the 868 band, or between `902000000` and `928000000` in the 915 band.
+* `tx_power` is the transmit power in dBm. It accepts between 2 and 14 for the 868 band, and between 5 and 20 in the 915 band.
+* `bandwidth` is the channel bandwidth in KHz. In the 868 band the accepted values are `LoRa.BW_125KHZ` and `LoRa.BW_250KHZ`. In the 915 band the accepted values are `LoRa.BW_125KHZ` and `LoRa.BW_500KHZ`.
+* `sf` sets the desired spreading factor. Accepts values between 7 and 12.
+* `preamble` configures the number of pre-amble symbols. The default value is 8.
+* `coding_rate` can take the following values: `LoRa.CODING_4_5`, `LoRa.CODING_4_6`, `LoRa.CODING_4_7` or `LoRa.CODING_4_8`.
+* `power_mode` can be either `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY` or `LoRa.SLEEP`. In `ALWAYS_ON` mode, the radio is always listening for incoming - packets whenever a transmission is not taking place. In `TX_ONLY` the radio goes to sleep as soon as the transmission completes. In `SLEEP` mode the radio is sent to sleep permanently and won't accept any commands until the power mode is changed.
+* `tx_iq` enables TX IQ inversion.
+* `rx_iq` enables RX IQ inversion.
+* `adr` enables Adaptive Data Rate.
+* `public` selects between the public and private sync word.
+* `tx_retries` sets the number of TX retries in `LoRa.LORAWAN` mode.
+* `device_class` sets the LoRaWAN device class. Can be either `LoRa.CLASS_A` or `LoRa.CLASS_C`.
+
+{{% hint style="info" %}}
+In `LoRa.LORAWAN` mode, only `adr`, `public`, `tx_retries` and `device_class` are used. All the other params will be ignored as they are handled by the LoRaWAN stack directly. On the other hand, in `LoRa.LORA` mode from those 4 arguments, only the public one is important in order to program the sync word. In `LoRa.LORA` mode `adr`, `tx_retries` and `device_class` are ignored since they are only relevant to the LoRaWAN stack.
+{{< /hint >}}
+
+For example, you can do:
+
+```python
+
+# initialize in raw LoRa mode
+lora.init(mode=LoRa.LORA, tx_power=14, sf=12)
+```
+
+or
+
+```python
+
+# initialize in LoRaWAN mode
+lora.init(mode=LoRa.LORAWAN)
+```
+
+#### lora.join(activation, auth, \* ,timeout=None, dr=None)
+
+Join a LoRaWAN network. Internally the stack will automatically retry every 15 seconds until a Join Accept message is received.
+
+The parameters are:
+
+* `activation`: can be either `LoRa.OTAA` or `LoRa.ABP`.
+* `auth`: is a tuple with the authentication data.
+* `timeout`: is the maximum time in milliseconds to wait for the Join Accept message to be received. If no timeout (or zero) is given, the call returns immediately and the status of the join request can be checked with `lora.has_joined()`.
+* `dr`: is an optional value to specify the initial data rate for the Join Request. Possible values are 0 to 5 for **EU868**, or 0 to 4 for **US915**.
+
+In the case of `LoRa.OTAA` the authentication tuple is: `(dev_eui, app_eui, app_key)` where `dev_eui` is optional. If it is not provided the LoRa MAC will be used. Therefore, you can do OTAA in 2 different ways:
+
+```python
+
+lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) # the device MAC address is used as DEV_EUI
+```
+
+or
+
+```python
+
+lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # a custom DEV_EUI is specified
+```
+
+Example:
+
+```python
+
+from network import LoRa
+import socket
+import time
+import ubinascii
+
+# Initialise LoRa in LORAWAN mode.
+# Please pick the region that matches where you are using the device:
+# Asia = LoRa.AS923
+# Australia = LoRa.AU915
+# Europe = LoRa.EU868
+# United States = LoRa.US915
+lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
+
+# create an OTAA authentication parameters
+app_eui = ubinascii.unhexlify('ADA4DAE3AC12676B')
+app_key = ubinascii.unhexlify('11B0282A189B75B0B4D2D8C7FA38548B')
+
+# join a network using OTAA (Over the Air Activation)
+lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0)
+
+# wait until the module has joined the network
+while not lora.has_joined():
+ time.sleep(2.5)
+ print('Not yet joined...')
+```
+
+In the case of `LoRa.ABP` the authentication tuple is: `(dev_addr, nwk_swkey, app_swkey)`. Example:
+
+```python
+
+from network import LoRa
+import socket
+import ubinascii
+import struct
+
+# Initialise LoRa in LORAWAN mode.
+# Please pick the region that matches where you are using the device:
+# Asia = LoRa.AS923
+# Australia = LoRa.AU915
+# Europe = LoRa.EU868
+# United States = LoRa.US915
+lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
+
+# create an ABP authentication params
+dev_addr = struct.unpack(">l", ubinascii.unhexlify('00000005'))[0]
+nwk_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
+app_swkey = ubinascii.unhexlify('2B7E151628AED2A6ABF7158809CF4F3C')
+
+# join a network using ABP (Activation By Personalisation)
+lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
+```
+
+#### lora.bandwidth(\[bandwidth\])
+
+Get or set the bandwidth in raw LoRa mode (`LoRa.LORA`). Can be either `LoRa.BW_125KHZ` (0), `LoRa.BW_250KHZ` (1) or `LoRa.BW_500KHZ` (2):
+
+```python
+
+# get raw LoRa Bandwidth
+lora.bandwidth()
+
+# set raw LoRa Bandwidth
+lora.bandwidth(LoRa.BW_125KHZ)
+```
+
+#### lora.frequency(\[frequency\])
+
+Get or set the frequency in raw LoRa mode (`LoRa.LORA`). The allowed range is between `863000000` and `870000000` Hz for the 868 MHz band version or between `902000000` and `928000000` Hz for the 915 MHz band version.
+
+```python
+
+# get raw LoRa Frequency
+lora.frequency()
+
+# set raw LoRa Frequency
+lora.frequency(868000000)
+```
+
+#### lora.coding\_rate(\[coding\_rate\])
+
+Get or set the coding rate in raw LoRa mode (`LoRa.LORA`). The allowed values are: `LoRa.CODING_4_5` (1), `LoRa.CODING_4_6` (2), `LoRa.CODING_4_7` (3) and `LoRa.CODING_4_8` (4).
+
+```python
+
+# get raw LoRa Coding Rate
+lora.coding_rate()
+
+# set raw LoRa Coding Rate
+lora.coding_rate(LoRa.CODING_4_5)
+```
+
+#### lora.preamble(\[preamble\])
+
+Get or set the number of preamble symbols in raw LoRa mode (`LoRa.LORA`):
+
+```python
+
+# get raw LoRa preamble symbols
+lora.preamble()
+
+# set raw LoRa preamble symbols
+lora.preamble(LoRa.CODING_4_5)
+```
+
+#### lora.sf(\[sf\])
+
+Get or set the spreading factor value in raw LoRa mode (`LoRa.LORA`). The minimum value is 7 and the maximum is 12:
+
+```python
+
+# get raw LoRa spread factor value
+lora.sf()
+
+# set raw LoRa spread factor value
+lora.sf(7)
+```
+
+#### lora.power\_mode(\[power\_mode\])
+
+Get or set the power mode in raw LoRa mode (`LoRa.LORA`). The accepted values are: `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY`, and `LoRa.SLEEP`:
+
+#### lora.stats()
+
+Return a named tuple with useful information from the last received LoRa or LoRaWAN packet. The named tuple has the following form:
+
+`(rx_timestamp, rssi, snr, sftx, sfrx, tx_trials, tx_power, tx_time_on_air, tx_counter, tx_frequency)`
+
+Example:
+
+```python
+
+lora.stats()
+```
+
+Where:
+
+* `rx_timestamp` is an internal timestamp of the last received packet with microseconds precision.
+* `rssi` holds the received signal strength in dBm.
+* `snr` contains the signal to noise ratio id dB (as a single precision float).
+* `sfrx` tells the data rate (in the case of LORAWAN mode) or the spreading factor (in the case of LORA mode) of the last packet received.
+* `sftx` tells the data rate (in the case of LORAWAN mode) or the spreading factor (in the case of LORA mode) of the last packet transmitted.
+* `tx_trials` is the number of tx attempts of the last transmitted packet (only relevant for LORAWAN confirmed packets).
+* `tx_power` is the power of the last transmission (in dBm).
+* `tx_time_on_air` is the time on air of the last transmitted packet (in ms).
+* `tx_counter` is the number of packets transmitted.
+* `tx_frequency` is the frequency used for the last transmission.
+
+#### lora.has\_joined()
+
+Returns `True` if a LoRaWAN network has been joined. `False` otherwise.
+
+#### lora.add\_channel(index, \* , frequency, dr\_min, dr\_max)
+
+Add a LoRaWAN channel on the specified `index`. If there's already a channel with that index it will be replaced with the new one.
+
+The arguments are:
+
+* `index`: Index of the channel to add. Accepts values between 0 and 15 for EU and between 0 and 71 for US.
+* `frequency`: Centre frequency in Hz of the channel.
+* `dr_min`: Minimum data rate of the channel (0-7).
+* `dr_max`: Maximum data rate of the channel (0-7).
+
+Examples:
+
+```python
+
+lora.add_channel(index=0, frequency=868000000, dr_min=5, dr_max=6)
+```
+
+#### lora.remove\_channel(index)
+
+Removes the channel from the specified `index`. On the 868MHz band the channels 0 to 2 cannot be removed, they can only be replaced by other channels using the `lora.add_channel` method. A way to remove all channels except for one is to add the same channel, 3 times on indexes 0, 1 and 2. An example can be seen below:
+
+```python
+
+lora.remove_channel()
+```
+
+On the 915MHz band there are no restrictions around this.
+
+#### lora.mac()
+
+Returns a byte object with the 8-Byte MAC address of the LoRa radio.
+
+#### lora.callback(trigger, handler=None, arg=None)
+
+Specify a callback handler for the LoRa radio. The `trigger` types are `LoRa.RX_PACKET_EVENT`, `LoRa.TX_PACKET_EVENT`, and `LoRa.TX_FAILED_EVENT`
+
+The `LoRa.RX_PACKET_EVENT` event is raised for every received packet. The `LoRa.TX_PACKET_EVENT` event is raised as soon as the packet transmission cycle ends, which includes the end of the receive windows (even if a downlink is received, the `LoRa.TX_PACKET_EVENT` will come last). In the case of non-confirmed transmissions, this will occur at the end of the receive windows, but, in the case of confirmed transmissions, this event will only be raised if the `ack` is received. If the `ack` is not received `LoRa.TX_FAILED_EVENT` will be raised after the number of `tx_retries` configured have been performed.
+
+An example of how this callback functions can be seen the in method [`lora.events()`](../lora#lora-events).
+
+#### lora.ischannel\_free(rssi\_threshold)
+
+This method is used to check for radio activity on the current LoRa channel, and if the `rssi` of the measured activity is lower than the `rssi_threshold` given, the return value will be `True`, otherwise `False`. Example:
+
+```python
+
+lora.ischannel_free(-100)
+```
+
+#### lora.set\_battery\_level(level)
+
+Set the battery level value that will be sent when the LoRaWAN MAC command that retrieves the battery level is received. This command is sent by the network and handled automatically by the LoRaWAN stack. The values should be according to the LoRaWAN specification:
+
+* `0` means that the end-device is connected to an external power source.
+* `1..254` specifies the battery level, 1 being at minimum and 254 being at maximum.
+* `255` means that the end-device was not able to measure the battery level.
+
+```python
+
+lora.set_battery_level(127) # 50% battery
+```
+
+#### lora.events()
+
+This method returns a value with bits sets (if any) indicating the events that have triggered the callback. Please note that by calling this function the internal events registry is cleared automatically, therefore calling it immediately for a second time will most likely return a value of 0.
+
+Example:
+
+```python
+
+def lora_cb(lora):
+ events = lora.events()
+ if events & LoRa.RX_PACKET_EVENT:
+ print('Lora packet received')
+ if events & LoRa.TX_PACKET_EVENT:
+ print('Lora packet sent')
+
+lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb)
+```
+
+#### lora.nvram\_save()
+
+Save the LoRaWAN state (joined status, network keys, packet counters, etc) in non-volatile memory in order to be able to restore the state when coming out of deepsleep or a power cycle.
+
+```python
+
+lora.nvram_save()
+```
+
+#### lora.nvram\_restore()
+
+Restore the LoRaWAN state (joined status, network keys, packet counters, etc) from non-volatile memory. State must have been previously stored with a call to `nvram_save` before entering deepsleep. This is useful to be able to send a LoRaWAN message immediately after coming out of deepsleep without having to join the network again. This can only be used if the current region matches the one saved.
+
+```python
+
+lora.nvram_restore()
+```
+
+#### lora.nvram\_erase()
+
+Remove the LoRaWAN state (joined status, network keys, packet counters, etc) from non-volatile memory.
+
+```python
+
+lora.nvram_erase()
+```
+
+## Constants
+
+* LoRa stack mode: `LoRa.LORA`, `LoRa.LORAWAN`
+* LoRaWAN join procedure: `LoRa.OTAA`, `LoRa.ABP`
+* Raw LoRa power mode: `LoRa.ALWAYS_ON`, `LoRa.TX_ONLY`, `LoRa.SLEEP`
+* Raw LoRa bandwidth: `LoRa.BW_125KHZ`, `LoRa.BW_250KHZ`, `LoRa.BW_500KHZ`
+* Raw LoRa coding rate: `LoRa.CODING_4_5`, `LoRa.CODING_4_6`, `LoRa.CODING_4_7`, `LoRa.CODING_4_8`
+* Callback trigger types (may be ORed): `LoRa.RX_PACKET_EVENT`, `LoRa.TX_PACKET_EVENT`, `LoRa.TX_FAILED_EVENT`
+* LoRaWAN device class: `LoRa.CLASS_A`, `LoRa.CLASS_C`
+* LoRaWAN regions: `LoRa.AS923`, `LoRa.AU915`, `LoRa.EU868`, `LoRa.US915`
+
+## Working with LoRa and LoRaWAN Sockets
+
+LoRa sockets are created in the following way:
+
+```python
+
+import socket
+s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
+```
+
+And they must be created after initialising the LoRa network card.
+
+LoRa sockets support the following standard methods from the socket module:
+
+#### socket.close()
+
+Usage:
+
+```python
+
+s.close()
+```
+
+#### socket.bind(port\_number)
+
+Usage:
+
+```python
+
+s.bind(1)
+```
+
+{{% hint style="info" %}}
+The `bind()` method is only applicable when the radio is configured in `LoRa.LORAWAN` mode.
+{{< /hint >}}
+
+#### socket.send(bytes)
+
+Usage:
+
+```python
+
+s.send(bytes([1, 2, 3]))
+```
+
+or
+
+```python
+
+s.send('Hello')
+```
+
+#### socket.recv(bufsize)
+
+Usage:
+
+```python
+
+s.recv(128)
+```
+
+#### socket.recvfrom(bufsize)
+
+This method is useful to know the destination port number of the message received. Returns a tuple of the form: `(data, port)`
+
+Usage:
+
+```python
+
+s.recvfrom(128)
+```
+
+#### socket.setsockopt(level, optname, value)
+
+Set the value of the given socket option. The needed symbolic constants are defined in the socket module (`SO_*` etc.). In the case of LoRa the values are always integers. Examples:
+
+```python
+
+# configuring the data rate
+s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)
+
+# selecting non-confirmed type of messages
+s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, False)
+
+# selecting confirmed type of messages
+s.setsockopt(socket.SOL_LORA, socket.SO_CONFIRMED, True)
+```
+
+{{% hint style="info" %}}
+Socket options are only applicable when the LoRa radio is used in LoRa.LORAWAN mode. When using the radio in LoRa.LORA mode, use the class methods to change the spreading factor, bandwidth and coding rate to the desired values.
+{{< /hint >}}
+
+#### socket.settimeout(value)
+
+Sets the socket timeout value in seconds. Accepts floating point values.
+
+Usage:
+
+```python
+
+s.settimeout(5.5)
+```
+
+#### socket.setblocking(flag)
+
+Usage:
+
+```python
+
+s.setblocking(True)
+```
diff --git a/content/firmwareapi/pycom/network/lora/pymesh.md b/content/firmwareapi/pycom/network/lora/pymesh.md
index 2260216..dd60641 100644
--- a/content/firmwareapi/pycom/network/lora/pymesh.md
+++ b/content/firmwareapi/pycom/network/lora/pymesh.md
@@ -1,5 +1,5 @@
---
-title: "Pymesh"
+title: "PyMesh"
aliases:
- firmwareapi/pycom/network/lora/pymesh.html
- firmwareapi/pycom/network/lora/pymesh.md
@@ -8,6 +8,7 @@ aliases:
This class provides Pymesh - LoRa Mesh protocol compliant for the LoRa network processor in the LoPy and FiPy. Below is an example demonstrating Pymesh initialisation and basic usage:
```python
+
from network import LoRa
# initialise LoRa
@@ -41,6 +42,7 @@ For various other complete Pymesh examples, check Tutorials & Examples section (
Create and configure the Mesh object.
```python
+
from network import LoRa
lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.EU868)
pymesh = lora.Mesh()
@@ -54,6 +56,7 @@ De-initialise Pymesh task. Any further Pymesh commands will return no answer.
To use again Pymesh the `LoRa.Mesh()` constructor has to be called.
```python
+
>>> pymesh.deinit()
True
>>> pymesh.neighbors()
@@ -72,6 +75,7 @@ Get node state inside Pymesh, which can be one of the following:
```
```python
+
# get node state inside Pymesh
>>> pymesh.state()
4
@@ -83,6 +87,7 @@ More info: https://openthread.io/guides/thread-primer/node-roles-and-types
Returns `True` if this node is the only Leader or Router in the current Mesh network.
```python
+
>>> pymesh.single()
True
```
@@ -92,6 +97,7 @@ True
Returns all the IPv6 unicast addresses assigned on Pymesh interface.
```python
+
>>> pymesh.ipaddr()
['fdde:ad00:beef:0:0:ff:fe00:fc00', 'fdde:ad00:beef:0:0:ff:fe00:cc00', 'fdde:ad00:beef:0:86c3:6130:98cc:6633', 'fe80:0:0:0:301:101:101:104']
```
@@ -118,6 +124,7 @@ More info: https://openthread.io/guides/thread-primer/ipv6-addressing
Returns the routing locator (RLOC) IPv6 address.
```python
+
>>> pymesh.rloc()
52224
>>> hex(pymesh.rloc())
@@ -138,6 +145,7 @@ For each neighbor the following properties are returned:
* age - number of seconds since last data packet was received.
```python
+
>>> pymesh.neighbors()
[(mac=1, role=3, rloc16=25600, rssi=-37, age=19),
(mac=8121069065142870746, role=3, rloc16=55296, rssi=-27, age=15)]
@@ -158,6 +166,7 @@ For each Router the following properties are returned:
* age - number of seconds since last keep-alive packet was received.
```python
+
>>> pymesh.routers()
[(mac=1, rloc16=25600, id=25, path_cost=1, age=12),
(mac=72340172838076676, rloc16=52224, id=51, path_cost=0, age=0),
@@ -177,6 +186,7 @@ The following details are returned:
* rloc16 - the Leader RLOC16.
```python
+
>>> pymesh.leader()
(part_id=828258, mac=72340172838076676, rloc16=52224)
```
@@ -189,6 +199,7 @@ has to be checked for incoming data.
Please check the following callback example.
```python
+
# handler responsible for receiving packets on UDP Pymesh socket
def receive_pack(sockets):
# listen for incoming packets on all sockets
@@ -244,6 +255,7 @@ Gets or sets as Border Router the current node, by specifying the external IPv6
* in case multiple Border Routers are being declared with the same prefix and the same path cost, the one with the highest preference is used.
```python
+
# IPv6 addresses, before setting Border Router
>>> pymesh.ipaddr()
['fdde:ad00:beef:0:0:ff:fe00:fc00', 'fdde:ad00:beef:0:0:ff:fe00:cc00', 'fdde:ad00:beef:0:86c3:6130:98cc:6633', 'fe80:0:0:0:301:101:101:104']
@@ -266,6 +278,7 @@ Removes a Border Router entry, by specifying the external IPv6 network address (
This will remove all IPv6 unicast from all Mesh nodes, which previously set an IPv6 with BR prefix.
```python
+
# BR entry
>>> mesh.mesh.border_router()
[(net='2001:dead:beef:caff::/64', preference=1)]
@@ -286,6 +299,7 @@ This will remove all IPv6 unicast from all Mesh nodes, which previously set an I
Sends a CLI command to the internal openthread engine; the list of CLI commands is [here](https://github.com/openthread/openthread/blob/c482301ec73b80985445102e4d0a936346172ddb/src/cli/README)
```python
+
# get the Leader data set
>>> print(pymesh.cli('leaderdata'))
Partition ID: 828258
@@ -303,6 +317,7 @@ Leader Router ID: 51
Pymesh supports only UDP sockets (not-acknowledged). They are created in the following way:
```python
+
import socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
```
@@ -324,6 +339,7 @@ Closes the socket.
Usage:
```python
+
s.close()
```
@@ -335,6 +351,7 @@ By default, if just `port_number` is used, then it binds the socket with all IPv
Usage:
```python
+
# binding socket with all IPv6 interfaces, like "::"
>>> s.bind(1234)
>>> mesh.ipaddr()
@@ -350,6 +367,7 @@ Sends `bytes` buffer to `ip`, on the designated UDP `port`. Returns the number o
Usage:
```python
+
>>> s.sendto("Hello World!", ("fdde:ad00:beef:0:0:ff:fe00:d800", 1234))
12
```
@@ -361,6 +379,7 @@ This method is useful to know the destination port number of the message receive
Usage:
```python
+
>>> s.recvfrom(512)
(b'Hello World!', ('fdde:ad00:beef:0:86c3:6130:98cc:6633', 1234))
```
diff --git a/content/firmwareapi/pycom/network/lte.md b/content/firmwareapi/pycom/network/lte.md
index 742d0c7..56f22d3 100644
--- a/content/firmwareapi/pycom/network/lte.md
+++ b/content/firmwareapi/pycom/network/lte.md
@@ -5,6 +5,7 @@ aliases:
- firmwareapi/pycom/network/lte.md
- chapter/firmwareapi/pycom/network/lte
---
+
The LTE class provides access to the LTE-M/NB-IoT modem on the GPy and FiPy. LTE-M/NB-IoT are new categories of cellular protocols developed by the [3GPP](http://www.3gpp.org) and optimised for long battery life power and longer range. These are new protocols currently in the process of being deployed by mobile networks across the world.
The GPy and FiPy support both new LTE-M protocols:
@@ -17,14 +18,27 @@ The GPy and FiPy support both new LTE-M protocols:
{{< /hint >}}
{{% hint style="info" %}}
-The Sequans modem used on Pycom's cellular enabled modules can only work in one of these modes at a time. In order to switch between the two protocols you need to flash a different firmware to the Sequans modem. Instructions for this can be found [here](/../../tutorials/lte/firmware).
+The Sequans modem used on Pycom's cellular enabled modules can only work in one of these modes at a time. In order to switch between the two protocols you need to flash a different firmware to the Sequans modem. Instructions for this can be found [here](/tutorials/lte/firmware).
+{{< /hint >}}
+
+{{% hint style="info" %}}
+
+**FiPy/Gpy Band Support**
+
+- Fipy/GPy v1.0 ==> supports 6 bands only (3, 4, 12, 13, 20, 28)
+
+- Fipy/GPy v1.2 with Sequans modem Firmware (41xxx) ==> Supports Full range of 17 bands (1, 2, 3, 4, 5, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 66)
+
+- Fipy/GPy v1.2 with Sequans older modem Firmwares (39xxx)==> Supports 8 Bands (3, 4, 5, 8, 12, 13, 20, 28)
+
+- Fipy/GPy v1.2 with Sequans old modem Firmwares < (39xxx)==> Supports 6 Bands (3, 4, 12, 13, 20, 28)
+
{{< /hint >}}
## AT Commands
The AT commands for the Sequans Monarch modem on the GPy/FiPy are available in a PDF file.
-
-{% file src="..//gitbook/assets/monarch\_4g-ez\_lr5110\_atcommands\_referencemanual\_rev3\_noconfidential.pdf" caption="AT Commands for Sequans" %}
+ AT Commands for Sequans
## Constructors
@@ -33,6 +47,7 @@ The AT commands for the Sequans Monarch modem on the GPy/FiPy are available in a
Create and configure a LTE object. See init for params of configuration.
```python
+
from network import LTE
lte = LTE()
```
@@ -54,9 +69,9 @@ Disables LTE modem completely. This reduces the power consumption to the minimum
#### lte.attach(\*, band=None, apn=None, cid=None, type=LTE.IP, legacyattach=True)
Enable radio functionality and attach to the LTE network authorised by the inserted SIM card. Optionally specify:
-
+
- `band` : to scan for networks. If no band (or `None`) is specified, all 8 bands will be scanned. The possible values for the band are: `3, 4, 5, 8, 12, 13, 20 and 28`.
-
+
- `apn` : Specify the APN (Access point Name).
- `cid` : connection ID, see `LTE.connect()`. when the ID is set here it will be remembered when doint connect so no need to specify again
@@ -69,7 +84,7 @@ Enable radio functionality and attach to the LTE network authorised by the inser
*NOTE* :
When carrier is specified in `LTE()` or `LTE.init()` (eg. `lte = LTE(carrier=verizon)`) No need to specify band, apn or type these parameters are already programmed in to the LTE modem for each carrier.
----
+---
#### lte.isattached()
@@ -90,6 +105,7 @@ Start a data session and obtain and IP address. Optionally specify a CID (Connec
For instance, to attach and connect to Verizon:
```python
+
import time
from network import LTE
@@ -123,12 +139,14 @@ Send an AT command directly to the modem. Returns the raw response from the mode
Example:
```python
+
lte.send_at_cmd('AT+CEREG?') # check for network registration manually (sames as lte.isattached())
```
Optionally the response can be parsed for pretty printing:
```python
+
def send_at_cmd_pretty(cmd):
response = lte.send_at_cmd(cmd).split('\r\n')
for line in response:
@@ -138,7 +156,7 @@ send_at_cmd_pretty('AT!="showphy"') # get the PHY status
send_at_cmd_pretty('AT!="fsm"') # get the System FSM
```
-- `delay` : specify maximum Timeout in ms to wait response from modem.
+- `delay` : specify the number of milliseconds the esp32 chip will wait between sending an AT command to the modem. and reading the response.
#### lte.imei()
@@ -165,9 +183,9 @@ Resumes PPP session with LTE modem.
Reset modem configuration to Factory settings.
#### lte.modem\_upgrade\_mode()
-
+
Puts the modem in to modem upgrade mode and bridging LTE modem UART port to FiPy/GPy UART0 to enable upgrading Firmware over USB port.
-
+
---
*NOTE* :
In this mode all All tasks on the board are halted and a reset is required to regain functionality.
@@ -190,4 +208,4 @@ Check Network Coverage for UE device (i.e LTE modem).
- `LTE.IP` : Internet Protocol IP
-- `LTE.IPV4V6` : Internet protocol ver. 4/6
\ No newline at end of file
+- `LTE.IPV4V6` : Internet protocol ver. 4/6
diff --git a/content/firmwareapi/pycom/network/server.md b/content/firmwareapi/pycom/network/server.md
index a49508d..e0e6f8b 100644
--- a/content/firmwareapi/pycom/network/server.md
+++ b/content/firmwareapi/pycom/network/server.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/network/server.md
- chapter/firmwareapi/pycom/network/server
---
+
The `Server` class controls the behaviour and the configuration of the FTP and telnet services running on the Pycom device. Any changes performed using this class' methods will affect both.
Example:
```python
+
import network
server = network.Server()
server.deinit() # disable the server
@@ -20,6 +22,7 @@ server.init(login=('user', 'password'), timeout=600)
## Quick Usage Example
```python
+
from network import Server
# init with new user, password and seconds timeout
diff --git a/content/firmwareapi/pycom/network/sigfox.md b/content/firmwareapi/pycom/network/sigfox.md
index 991b281..3bb5658 100644
--- a/content/firmwareapi/pycom/network/sigfox.md
+++ b/content/firmwareapi/pycom/network/sigfox.md
@@ -5,14 +5,16 @@ aliases:
- firmwareapi/pycom/network/sigfox.md
- chapter/firmwareapi/pycom/network/sigfox
---
+
Sigfox is a Low Power Wide Area Network protocol that enables remote devices to connect using ultra-narrow band, UNB technology. The protocol is bi-directional, messages can both be sent up to and down from the Sigfox servers.
{{% hint style="info" %}}
-When operating in `RCZ2` and `RCZ4` the module can only send messages on the default macro-channel (this is due to Sigfox network limitations). Therefore, the device needs to reset automatically to the default macro-channel after every 2 transmissions. However, due to FCC duty cycle limitations, there must a minimum of a 20s delay after resetting to the default macro-channel. Our API takes care of this, (and in real life applications you should not be in the need to send Sigfox messages that often), so it will wait for the necessary amount of time to make sure that the duty cycle restrictions are fulfilled.
+When operating in RCZ2 and RCZ4 the module can only send messages on the default macro-channel (this is due to Sigfox network limitations). Therefore, the device needs to reset automatically to the default macro-channel after every 2 transmissions. However, due to FCC duty cycle limitations, there must a minimum of a 20s delay after resetting to the default macro-channel. Our API takes care of this, (and in real life applications you should not be in the need to send Sigfox messages that often), so it will wait for the necessary amount of time to make sure that the duty cycle restrictions are fulfilled.
This means that if you run a piece of test code like:
```python
+
for i in range(1, 100):
# send something
s.send('Hello ' + str(i))
@@ -26,6 +28,7 @@ This class provides a driver for the Sigfox network processor in the Sigfox enab
## Quick Usage Example
```python
+
from network import Sigfox
import socket
@@ -56,6 +59,7 @@ Please ensure that there is an antenna connected to your device before sending/r
Create and configure a Sigfox object. See init for params of configuration. Examples:
```python
+
# configure radio for the Sigfox network, using RCZ1 (868 MHz)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
@@ -64,7 +68,7 @@ sigfox = Sigfox(mode=Sigfox.FSK, frequency=912000000)
```
{{% hint style="info" %}}
-`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
+Sigfox.FSK mode is not supported on LoPy 4 and FiPy.
{{< /hint >}}
## Methods
@@ -103,6 +107,7 @@ Returns a byte object with the 8-Byte bytes object with the Sigfox PAC.
To return human-readable values you should import `ubinascii` and convert binary values to hexidecimal representation. For example:
```python
+
print(ubinascii.hexlify(sigfox.mac()))
```
{{< /hint >}}
@@ -116,6 +121,7 @@ Returns a tuple of the form: `(uplink_frequency_hz, downlink_frequency_hz)`
Sets or gets the public key flag. When called passing a `True` value the Sigfox public key will be used to encrypt the packets. Calling it without arguments returns the state of the flag.
```python
+
# enable encrypted packets
sigfox.public_key(True)
@@ -139,6 +145,7 @@ sigfox.public_key()
Sigfox sockets are created in the following way:
```python
+
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
```
@@ -156,6 +163,7 @@ Use it to close an existing socket.
In Sigfox mode the maximum data size is 12 bytes. In FSK the maximum is 64.
```python
+
# send a Sigfox payload of bytes
s.send(bytes([1, 2, 3]))
@@ -168,6 +176,7 @@ s.send('Hello')
This method can be used to receive a Sigfox downlink or FSK message.
```python
+
# size of buffer should be passed for expected payload, e.g. 64 bytes
s.recv(64)
```
@@ -177,6 +186,7 @@ s.recv(64)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module (`SO_*` etc.). In the case of Sigfox the values are always an integer. Examples:
```python
+
# wait for a downlink after sending the uplink packet
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
@@ -196,6 +206,7 @@ s.setsockopt(socket.SOL_SIGFOX, socket.SO_BIT, False)
Sending a Sigfox packet with a single bit is achieved by sending an empty string, i.e.:
```python
+
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
@@ -217,12 +228,14 @@ If the socket is set to blocking, your code will be wait until the socket comple
A Sigfox capable Pycom devices (SiPy) can both send and receive data from the Sigfox network. To receive data, a message must first be sent up to Sigfox, requesting a downlink message. This can be done by passing a `True` argument into the `setsockopt()` method.
```python
+
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
```
An example of the downlink procedure can be seen below:
```python
+
# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
@@ -247,12 +260,13 @@ s.recv(32)
To communicate between two Sigfox capable devices, it may be used in FSK mode. Two devices are required to be set to the same frequency, both using FSK.
{{% hint style="info" %}}
-`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
+Sigfox.FSK mode is not supported on LoPy 4 and FiPy.
{{< /hint >}}
**Device 1**:
```python
+
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
@@ -267,6 +281,7 @@ while True:
**Device 2**:
```python
+
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
diff --git a/content/firmwareapi/pycom/network/wlan.md b/content/firmwareapi/pycom/network/wlan.md
index bf0c138..302a158 100644
--- a/content/firmwareapi/pycom/network/wlan.md
+++ b/content/firmwareapi/pycom/network/wlan.md
@@ -5,9 +5,11 @@ aliases:
- firmwareapi/pycom/network/wlan.md
- chapter/firmwareapi/pycom/network/wlan
---
+
This class provides a driver for the WiFi network processor in the module. Example usage:
```python
+
import network
import time
# setup as a station
@@ -23,6 +25,7 @@ print(wlan.ifconfig())
## Quick Usage Example
```python
+
import machine
from network import WLAN
@@ -39,9 +42,9 @@ print(wlan.ifconfig())
## Constructors
-### class network.WLAN(id=0, ...)
+#### class network.WLAN(id=0, ...)
-Create a WLAN object, and optionally configure it. See [`init`](../wlan#wlan-init-mode-ssid-none-auth-none-channel-1-antenna-none-power_save-false-hidden-false) for params of configuration.
+Create a WLAN object, and optionally configure it. See [`init`](../wlan.md#wlan-init-mode-ssid-none-auth-none-channel-1-antenna-none-power_save-false-hidden-false) for params of configuration.
{{% hint style="info" %}}
The WLAN constructor is special in the sense that if no arguments besides the `id` are given, it will return the already existing WLAN instance without re-configuring it. This is because WLAN is a system feature of the WiPy. If the already existing instance is not initialised it will do the same as the other constructors an will initialise it with default values.
@@ -49,7 +52,7 @@ The WLAN constructor is special in the sense that if no arguments besides the `i
## Methods
-#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False, bandwidth=HT40, max\_tx\_pwr=20, country=CN)
+#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False)
Set or get the WiFi network processor configuration.
@@ -66,13 +69,11 @@ Arguments are:
* `power_save` enables or disables power save functions in `STA` mode.
* `hidden` only valid in `WLAN.AP` mode to create an access point with a hidden SSID when set to `True`.
-* `bandwidth` is the Bandwidth to use, either 20MHz or 40 MHz , use `HT20` or `HT40`
-* `max_tx_pwr` is the maximum WiFi Tx power allowed. see `WLAN.max_tx_power()` for more details
-* `country` tuple representing the country configuration parameters. see `WLAN.country()` for more details
For example, you can do:
```python
+
# create and configure as an access point
wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT)
```
@@ -80,15 +81,25 @@ wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channe
or
```python
+
# configure as an station
wlan.init(mode=WLAN.STA)
```
-### wlan.deinit()
+{{% hint style="info" %}}
+To use an external antenna, set `P12 as output pin.`
+
+```python
+
+Pin('P12', mode=Pin.OUT)(True)
+```
+{{< /hint >}}
+
+#### wlan.deinit()
Disables the WiFi radio.
-### wlan.connect(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=None, hostname=None)
+#### wlan.connect(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=None)
Connect to a wifi access point using the given SSID, and other security parameters.
@@ -101,48 +112,24 @@ Connect to a wifi access point using the given SSID, and other security paramete
* `keyfile` is the path to the client key. Only used if `username` and `password` are not part of the `auth` tuple.
* `certfile` is the path to the client certificate. Only used if `username` and `password` are not part of the `auth` tuple.
* `identity` is only used in case of `WLAN.WPA2_ENT` security. Needed by the server.
-* `hostname` is the name of the host connecting to the AP. Max length of name string is 32 Bytes
{{% hint style="info" %}}
The ESP32 only handles certificates with `pkcs8` format (but not the "Traditional SSLeay RSAPrivateKey" format). The private key should be RSA coded with 2048 bits at maximum.
{{< /hint >}}
-#### wlan.scan(\[ssid=NULL, bssid=NULL, channel=0, show\_hidden=False, type=WLAN.SCAN\_ACTIVE, scantime=120ms\])
+#### wlan.scan()
-Performs a network scan and returns a list of named tuples with (ssid, bssid, sec, channel, rssi). When no config args passed scan will be performed with default configurations.
+Performs a network scan and returns a list of named tuples with `(ssid, bssid, sec, channel, rssi)`. Note that channel is always `None` since this info is not provided by the WiPy.
-Note: For Fast scan mode ssid/bssid and channel should be
-
-* `ssid` : If the SSID is not NULL, it is only the AP with the same SSID that can be scanned.
-* `bssid` : If the BSSID is not NULL, it is only the AP with the same BSSID that can be scanned. The bssid is given as 6 Hexadecimal bytes literals (i.e b'\xff\xff\xff\xff\xff\xff')
-* `channel` : If “channel” is 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan.
-* `show_hidden` : If “show\_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise, the scan considers the hidden AP a normal one.
-* `type` : If “type” is `WLAN.SCAN_ACTIVE`, the scan is “active”; otherwise, it is a “passive” one.
- * Active Scan is performed by sending a probe request. The default scan is an active scan
- * Passive Scan sends no probe request. Just switch to the specific channel and wait for a beacon.
-* `scantime` :
-
- This field is used to control how long the scan dwells on each channel. For passive scans, scantime=\[int\] designates the dwell time for each channel.
-
- For active scans, dwell times for each channel are listed below. scantime is given as a tuple for min and max times (min,max)
-
-min=0, max=0: scan dwells on each channel for 120 ms.
-
-min>0, max=0: scan dwells on each channel for 120 ms.
-
-min=0, max>0: scan dwells on each channel for max ms.
-
-min>0, max>0: The minimum time the scan dwells on each channel is min ms. If no AP is found during this time frame, the scan switches to the next channel. Otherwise, the scan dwells on the channel for max ms.If you want to improve the performance of the the scan, you can try to modify these two parameters.
-
-### wlan.disconnect()
+#### wlan.disconnect()
Disconnect from the WiFi access point.
-### wlan.isconnected()
+#### wlan.isconnected()
In case of STA mode, returns `True` if connected to a WiFi access point and has a valid IP address. In AP mode returns `True` when a station is connected, `False` otherwise.
-### wlan.ifconfig(id=0, config=\['dhcp' or configtuple\])
+#### wlan.ifconfig(id=0, config=\['dhcp' or configtuple\])
When `id` is 0, the configuration will be get/set on the Station interface. When `id` is 1 the configuration will be done for the AP interface.
@@ -153,200 +140,45 @@ If `dhcp` is passed as a parameter then the DHCP client is enabled and the IP pa
If the 4-tuple config is given then a static IP is configured. For instance:
```python
+
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
```
-### wlan.mode(\[mode\])
+#### wlan.mode(\[mode\])
Get or set the WLAN mode.
-### wlan.ssid(\[ssid\])
+#### wlan.ssid(\[ssid\])
-Get or set the SSID (Set SSID of AP).
+Get or set the SSID when in AP mode.
-In case if mode = `WLAN.STA` this method can get the ssid of AP the board is connected to.
-
-In case of mode = `WLAN.AP` this method can get the ssid of the board's own AP.
-
-In case of mode = `WLAN.STA_AP` this method can get the ssid of board's own AP plus the AP the STA is connected to in form of a tuple:
-
-_\_
-
-### wlan.auth(\[auth\])
+#### wlan.auth(\[auth\])
Get or set the authentication type when in AP mode.
-### wlan.channel(\[channel, sec\_chn\])
+#### wlan.channel(\[channel\])
-_In AP mode:_
+Get or set the channel (only applicable in AP mode).
-Get or set the wifi channel
-
-_In STA mode:_
-
-`channel`: is the primary channel to listen to.
-
-`sec_chn` : Only in case of Bandwidth = HT40 this should specify the position of the secondary channel weather above or below primary channel. `WLAN.SEC_CHN_POS_ABOVE` or `WLAN.SEC_CHN_POS_BELOW`
-
-_Note: Setting Channel in STA mode is only Allowed in Promiscuous mode_
-
-### wlan.antenna(\[antenna\])
+#### wlan.antenna(\[antenna\])
Get or set the antenna type (external or internal).
-### wlan.mac(\[mac, mode\])
-
-when no arguments are passed a 6-byte long `bytes` tuple object with the WiFI MAC address of both Wifi Station mode and Acces Point mode
-
-`mac`: a 6 bytes bytearray mac address
-
-`mode`: The Interface to set the given MAC address to `WLAN.STA` or `WLAN.AP`
-
-Ex: To set the mac address of Wifi Station mode:
+{{% hint style="info" %}}
+To use an external antenna, set `P12 as output pin.`
```python
-wlan.mac(bytearray([0xAE, 0x77, 0x88, 0x99, 0x22, 0x44]), WLAN.STA)
+
+Pin('P12', mode=Pin.OUT)(True)
```
+{{< /hint >}}
-_Note: STA and AP cannot have the Same Mac Address_
+#### wlan.mac()
-### wlan.bandwidth()
-
-Set the bandwidth of the wifi, either 20 MHz or 40 MHz can be configured, use constants `HT20` or `HT40`
-
-### wlan.hostname()
-
-Set the Host name of the device connecting to the AP in case of Wifi `mode=WLAN.STA`, in case of `mode=WLAN.AP` this is the name of the host hosting the AP. Max length of name string is 32 Bytes
-
-### wlan.ap\_sta\_list()
-
-Gets an info list of all stations connected to the board's AP.
-
-Info returned is a list of tuples containning (\[mac address of connected STA\], \[average rssi value\], \[Wlan protocol enabled by STA\]).
-
-Protocol types are either : `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N` or `WLAN.PHY_LOW_RATE`
-
-### wlan.max\_tx\_power(\[power\])
-
-Gets or Sets the maximum allowable transmission power for wifi.
-
-Packets of different rates are transmitted in different powers according to the configuration in phy init data. This API only sets maximum WiFi transmiting power. If this API is called, the transmiting power of every packet will be less than or equal to the value set by this API. Default is Level 0.
-
-Values passed in power are mapped to transmit power levels as follows:
-
-* \[78, 127\]: level0
-* \[76, 77\]: level1
-* \[74, 75\]: level2
-* \[68, 73\]: level3
-* \[60, 67\]: level4
-* \[52, 59\]: level5
-* \[44, 51\]: level5 - 2dBm
-* \[34, 43\]: level5 - 4.5dBm
-* \[28, 33\]: level5 - 6dBm
-* \[20, 27\]: level5 - 8dBm
-* \[8, 19\]: level5 - 11dBm
-* \[-128, 7\]: level5 - 14dBm
-
-### wlan.country(\[country, schan, nchan, max\_tx\_pwr, policy\])
-
-Gets or set s Country configuration parameters for wifi.
-
-* `country` That is the country name code , it is max 2 characters string representing the country eg: "CN" for china nad "NL" for Netherlands
-* `scahn` is the start channel number, in scan process scanning will be performed starting from this channels till the total number of channels. it should be less than or equal 14.
-* `nchan` is the total number of channels in the specified country. maximum is 14
-* `max_tx_pwr` Maximum transmission power allowed. see `WLAN.max_tx_power()` for more details.
-* `policy` Is the method when setting country configuration for `WLAN.COUNTRY_POL_AUTO` in STA mode the wifi will aquire the same country config of the connected AP, for `WLAN.COUNTRY_POL_MAN` the configured country parameters will take effect regardless of Connected AP.
-
-### wlan.joined\_ap\_info()
-
-Returns a tuple with (bssid, ssid, primary channel, rssi, Authorization method, wifi standard used) of the connected AP in case of STA mode.
-
-### wlan.wifi\_protocol(\[(bool PHY11\_\_B, bool PHY11\_G, bool PHY11\_N)\])
-
-Sets or gets Wifi Protocol supported.
-
-### wlan.send\_raw(Buffer, interface=STA, use\_sys\_seq=True)
-
-Send raw data through the Wifi Interface.
-
-`Buffer`: Buffer of bytes object Containning Data to be transmitted. Data should not be greater than 1500 nor smaller than 24.
-
-`interface`: The Interface to use for transmitting Data AP or STA in case the mode used is APSTA. other wise the interface currently active will be used.
-
-`use_sys_seq`: `True` to use the systems next sequance number for sending the data, `False` for keeping the sequance number in the given raw data buffer unchanged.
-
-### wlan.callback(trigger, handler=Null, arg=Null)
-
-Register a user callback function `handler` to be called once any of the `trigger` events occures optionally with a passed `arg`. by default the wlan obj is passed as arg to the handler. To unregister the callback you can call the `wlan.callback` function with empty `handler` and `arg` parameters.
-
-For trigger events see `Constants` section.
-
-### wlan.promiscuous(\[bool\])
-
-* To enable Promiscuous mode `WLAN.promiscuous(True)` should be called, and `WLAN.promiscuous(False)` for disabling
-* To get current mode setting call function with empty args
-
-Note:
-
-* Promiscuous mode should be enabled for Wifi packets types Events to be triggered
-* for changing wifi channel via `wlan.channel()` promiscuous mode should be enabled.
-
-### wlan.events()
-
-This function will return an integer object as mask for triggered events.
-
-### wlan.wifi\_packet()
-
-This function will return a tuble with Wifi packet info captured in promiscuous mode.
-
-### wlan.ctrl\_pkt\_filter(\[int\])
-
-This function is used to set the filter mask for Wifi control packets in promiscuous mode. for Filter masks, see `Constants` section.
-
-To get the current Filter mask, call the function with empty args.
+Get a 6-byte long `bytes` object with the WiFI MAC address.
## Constants
* WLAN mode: `WLAN.STA`, `WLAN.AP`, `WLAN.STA_AP`
* WLAN network security: `WLAN.WEP`, `WLAN.WPA`, `WLAN.WPA2`, `WLAN.WPA2_ENT`
* Antenna type: `WLAN.INT_ANT`, `WLAN.EXT_ANT`
-* WLAN Bandwidth: `WLAN.HT20`, `WLAN.HT40`
-* WLAN protocol: `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N`, `WLAN.PHY_LOW_RATE`
-* Scan Type: `WLAN.SCAN_ACTIVE` `WLAN.SCAN_PASSIVE`
-* WLAN country config policy: `WLAN.COUNTRY_POL_AUTO`, `WLAN.COUNTRY_POL_MAN`
-* Secondary Channel position: `WLAN.SEC_CHN_POS_ABOVE`, `WLAN.SEC_CHN_POS_BELOW`
-* Wlan callback triggers:
-
- `WLAN.EVENT_PKT_MGMT`: Managment packet recieved in promiscuous mode.
-
- `WLAN.EVENT_PKT_CTRL`: Control Packet recieved in promiscuous mode
-
- `WLAN.EVENT_PKT_DATA`: Data packet recieved in promiscuous mode
-
- `WLAN.EVENT_PKT_DATA_MPDU`: MPDU data packet recieved in promiscuous mode
-
- `WLAN.EVENT_PKT_DATA_AMPDU`: AMPDU data packet recieved in promiscuous mode
-
- `WLAN.EVENT_PKT_MISC`: misc paket recieved in promiscuous mode.
-
- `WLAN.EVENT_PKT_ANY`: Any packet recieved in promiscuous mode.
-
-* Control packet filters in promiscuous mode:
-
- `WLAN.FILTER_CTRL_PKT_ALL`: Filter all Control packets
-
- `WLAN.FILTER_CTRL_PKT_WRAPPER`: Filter control wrapper packets
-
- `WLAN.FILTER_CTRL_PKT_BAR`: Filter Control BAR packets
-
- `WLAN.FILTER_CTRL_PKT_BA`: Filter Control BA packets
-
- `WLAN.FILTER_CTRL_PKT_PSPOLL`: Filter Control PSPOLL Packets
-
- `WLAN.FILTER_CTRL_PKT_CTS`: Filter Control CTS packets
-
- `WLAN.FILTER_CTRL_PKT_ACK`: Filter Control ACK packets
-
- `WLAN.FILTER_CTRL_PKT_CFEND`: Filter Control CFEND Packets
-
- `WLAN.FILTER_CTRL_PKT_CFENDACK`: Filter Control CFENDACK Packets
diff --git a/content/firmwareapi/pycom/pycom.md b/content/firmwareapi/pycom/pycom.md
index 9f85ab1..bb5daa3 100644
--- a/content/firmwareapi/pycom/pycom.md
+++ b/content/firmwareapi/pycom/pycom.md
@@ -5,11 +5,13 @@ aliases:
- firmwareapi/pycom/pycom.md
- chapter/firmwareapi/pycom/pycom
---
+
The `pycom` module contains functions to control specific features of the Pycom devices, such as the heartbeat RGB LED.
## Quick Usage Example
```python
+
import pycom
pycom.heartbeat(False) # disable the heartbeat LED
@@ -37,6 +39,7 @@ Set the colour of the RGB LED. The colour is specified as 24 bit value represent
Set the value of the specified key in the NVRAM memory area of the external flash. Data stored here is preserved across resets and power cycles. Value can only take 32-bit integers at the moment. Example:
```python
+
import pycom
pycom.nvs_set('temp', 25)
@@ -48,6 +51,7 @@ pycom.nvs_set('count', 10)
Get the value the specified key from the NVRAM memory area of the external flash. Example:
```python
+
import pycom
pulses = pycom.nvs_get('count')
@@ -68,6 +72,7 @@ Erase the entire NVRAM memory area.
Get or set the WiFi on boot flag. When this flag is set to `True`, the AP with the default SSID (`lopy-wlan-xxx` for example) will be enabled as part of the boot process. If the flag is set to False, the module will boot with WiFi disabled until it's enabled by the script via the `WLAN` class. This setting is stored in non-volatile memory which preserves it across resets and power cycles. Example:
```python
+
import pycom
pycom.wifi_on_boot(True) # enable WiFi on boot
@@ -79,6 +84,7 @@ pycom.wifi_on_boot() # get the wifi on boot flag
Enables the WDT at boot time with the timeout in ms set by the function `wdt_on_boot_timeout`. If this flag is set, the application needs to reconfigure the WDT with a new timeout and feed it regularly to avoid a reset.
```python
+
import pycom
pycom.wdt_on_boot(True) # enable WDT on boot
@@ -90,6 +96,7 @@ pycom.wdt_on_boot() # get the WDT on boot flag
Sets or gets the WDT on boot timeout in milliseconds. The minimum value is 5000 ms.
```python
+
import pycom
pycom.wdt_on_boot_timeout(10000) # set the timeout to 5000ms
@@ -103,6 +110,7 @@ Return a list of pulses at `pin`. The methods scans for transitions at `pin` and
Example:
```python
+
# get the raw data from a DHT11/DHT22/AM2302 sensor
from machine import Pin
from pycom import pulses_get
@@ -126,6 +134,7 @@ Perform a firmware update. These methods are internally used by a firmware updat
Example:
```python
+
# Firmware update by reading the image from the SD card
#
from pycom import ota_start, ota_write, ota_finish
@@ -156,13 +165,3 @@ with open(APPIMG, "rb") as f:
Instead of reading the data to be written from a file, it can obviously also be received from a server using any suitable protocol, without the need to store it in the devices file system.
-#### pycom.bootmgr(boot\_partition=pycom.FACTORY, fs\_type=FAT, safeboot=False, reset=False)
-
-* `boot_partition` This is to set the partition to boot from , this could be set to either `pycom.FACTORY` or `pycom.OTA_0`
-* `fs_type` This is to set the filesystem to use for the flash memory (`/flash`). This could be set to `pycom.FAT` for FAT16 or `pycom.LittleFS` for LittleFS filesystem.
-
- _Note: When the firmware is built with option_ `FS_USE_LITTLEFS` _the file system for_ `/flash` _is forced to be LittleFS._
-
-* `safeboot` Enable or Disable safemoot mode.
-* `reset` Set `True` to reset target after updating the `bootmgr` options , `False` for not resetting.
-
diff --git a/content/gettingstarted/.DS_Store b/content/gettingstarted/.DS_Store
new file mode 100644
index 0000000..d9b2e5c
Binary files /dev/null and b/content/gettingstarted/.DS_Store differ
diff --git a/content/gettingstarted/_index.md b/content/gettingstarted/_index.md
index e67199f..3f0cc79 100644
--- a/content/gettingstarted/_index.md
+++ b/content/gettingstarted/_index.md
@@ -1,18 +1,16 @@
---
-title: "Introduction"
+title: ""
aliases:
- gettingstarted/introduction.html
- gettingstarted/introduction.md
- - gettingstarted/introduction
- chapter/gettingstarted
- getting-started
- - gettingstarted
- - getting-started/introduction
+ - gettingstarted/introduction
- chapter/gettingstarted/introduction
-
disable_breadcrumbs: true
---
-So, you've decided to order a Pycom development module. Firstly we would like to congratulate you in making an excellent decision. If you haven't yet placed your order we highly recommend you check out the [products](/products) page before you place your order to ensure you know which accessories you might require.
+
+So, you've decided to order a Pycom development module. Firstly we would like to congratulate you in making an excellent decision. If you haven't yet placed your order we highly recommend you check out the [products](../products) page before you place your order to ensure you know which accessories you might require.

diff --git a/content/gettingstarted/connection/.DS_Store b/content/gettingstarted/connection/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/content/gettingstarted/connection/.DS_Store differ
diff --git a/content/gettingstarted/connection/gpy.md b/content/gettingstarted/connection/gpy.md
index d20ea39..c8db969 100644
--- a/content/gettingstarted/connection/gpy.md
+++ b/content/gettingstarted/connection/gpy.md
@@ -96,8 +96,6 @@ aliases:
----
-
## Antennas
### LTE Cat-M1/NB-IoT
diff --git a/content/gettingstarted/connection/lopy.md b/content/gettingstarted/connection/lopy.md
index f090031..861fcae 100644
--- a/content/gettingstarted/connection/lopy.md
+++ b/content/gettingstarted/connection/lopy.md
@@ -108,8 +108,6 @@ aliases:
-***
-
## Antennas
diff --git a/content/gettingstarted/connection/lopy4.md b/content/gettingstarted/connection/lopy4.md
index f04ebdf..5493fae 100644
--- a/content/gettingstarted/connection/lopy4.md
+++ b/content/gettingstarted/connection/lopy4.md
@@ -109,8 +109,6 @@ aliases:
----
-
## Antennas
### Lora/Sigfox
diff --git a/content/gettingstarted/installation/_index.md b/content/gettingstarted/installation/_index.md
index e68cb9d..0f9a80c 100644
--- a/content/gettingstarted/installation/_index.md
+++ b/content/gettingstarted/installation/_index.md
@@ -1,10 +1,11 @@
---
-title: "Software"
+title: "Software setup"
aliases:
+ - chapter/gettingstarted/installation/installingsoftware
---
+
To get you up and running, Pycom provides a suite of tools to assist with developing and programming your Pycom Devices:
1. [**Drivers:**](drivers) If you are using Microsoft Windows, you might be required to install drivers for our products to function correctly.
2. [**Pycom firmware update utility:**](firmwaretool) This tool automates the process of upgrading the firmware of your Pycom device. It is important that you use this tool before you attempt to use your device. Not only to ensure you have the most stable and feature packed firmware, but also to ensure all the functionality of your device is enable. E.g. this tool also activates your two year free sigfox connectivity.
3. [**Development Environment:**](pymakr) Pymakr is a plug-in for Atom and Visual Studio Code developed by Pycom to make development for Pycom modules super easy. It allows you to use your favourite text editor while simplifying the process of uploading code to the device.
-
diff --git a/content/gettingstarted/installation/drivers.md b/content/gettingstarted/installation/drivers.md
index 52de00f..79c0f95 100644
--- a/content/gettingstarted/installation/drivers.md
+++ b/content/gettingstarted/installation/drivers.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/installation/drivers.md
- chapter/gettingstarted/installation/drivers
---
+
## Linux
You should not need to install any drivers for our devices to be recognised by Linux. You may how ever need to adjust permissions to make sure you have access to the serial port. On most distributions this can be done by adding your user to the `dialout` user group. Please check the specific instructions for your linux distribution for how to do this.
@@ -21,7 +22,8 @@ All our products will work out of the box for Windows 8/10/+. If using Windows 7
Please download the driver software from the link below.
-[Pysense/Pytrack/Pyscan/Expansion Board 3.0 Serial Driver](https://github.com/pycom/pycom-docs/tree/37661883902849b1a931ee273a23ae8e0f3d773e/chapter/pytrackpysense/installation/pycom.inf)
+[Pysense/Pytrack/Pyscan/Expansion Board 3.0 Serial Driver (save the file to your computer)](https://raw.githubusercontent.com/pycom/pycom-documentation/master/pytrackpysense/installation/pycom.inf)
+
### Installation
diff --git a/content/gettingstarted/installation/pymakr.md b/content/gettingstarted/installation/pymakr.md
index bdec272..e9f21a1 100644
--- a/content/gettingstarted/installation/pymakr.md
+++ b/content/gettingstarted/installation/pymakr.md
@@ -5,12 +5,13 @@ aliases:
- gettingstarted/installation/pymakr.md
- chapter/gettingstarted/installation/pymakr
---
+

## Pymakr Plugins
To make it as easy as possible Pycom has developed a plugin for two popular text editors, called Pymakr. These plugins have been built and are available for the following platforms:
-{{% refname "/pymakr/installation/atom.md" %}}
+- {{% refname "/pymakr/installation/atom" %}}
-{{% refname "/pymakr/installation/vscode.md" %}}
+- {{% refname "/pymakr/installation/vscode" %}}
diff --git a/content/gettingstarted/programming/README.md b/content/gettingstarted/programming/README.md
index 10db8f4..6d0c858 100644
--- a/content/gettingstarted/programming/README.md
+++ b/content/gettingstarted/programming/README.md
@@ -3,6 +3,7 @@ title: "Programming the modules"
aliases:
- chapter/gettingstarted/programming
---
+
Now that you have connected and updated your pycom module and installed all the required software on your computer, we can begin programming your Pycom module.
If this is your first time using a Pycom module we highly recommend you read through the following pages:
diff --git a/content/gettingstarted/programming/_index.md b/content/gettingstarted/programming/_index.md
index 6a77a28..7df6c81 100644
--- a/content/gettingstarted/programming/_index.md
+++ b/content/gettingstarted/programming/_index.md
@@ -2,6 +2,7 @@
title: "Programming the modules"
aliases:
---
+
Now that you have connected and updated your pycom module and installed all the required software on your computer, we can begin programming your Pycom module.
If this is your first time using a Pycom module we highly recommend you read through the following pages:
diff --git a/content/gettingstarted/programming/examples.md b/content/gettingstarted/programming/examples.md
index 479592d..05f3278 100644
--- a/content/gettingstarted/programming/examples.md
+++ b/content/gettingstarted/programming/examples.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/programming/examples.md
- chapter/gettingstarted/programming/examples
---
+
To get you started with Python (MicroPython) syntax, we've provided you with a number of code examples.
## Variable Assignment
@@ -12,6 +13,7 @@ To get you started with Python (MicroPython) syntax, we've provided you with a n
As with Python 3.5, variables can be assigned to and referenced. Below is an example of setting a variable equal to a string and then printing it to the console.
```python
+
variable = "Hello World"
print(variable)
```
@@ -21,6 +23,7 @@ print(variable)
Conditional statements allow control over which elements of code run depending on specific cases. The example below shows how a temperature sensor might be implemented in code.
```python
+
temperature = 15
target = 10
if temperature > target:
@@ -38,6 +41,7 @@ Loops are another important feature of any programming language. This allows you
`for` loops allow you to control how many times a block of code runs for within a range.
```python
+
x = 0
for y in range(0, 9):
x += 1
@@ -47,6 +51,7 @@ print(x)
`while` loops are similar to `for` loops, however they allow you to run a loop until a specific conditional is `true/false`. In this case, the loop checks if `x` is less than `9` each time the loop passes.
```python
+
x = 0
while x < 9:
x += 1
@@ -60,6 +65,7 @@ Functions are blocks of code that are referred to by name. Data can be passed in
The function below takes two numbers and adds them together, outputting the result.
```python
+
def add(number1, number2):
return number1 + number2
@@ -69,6 +75,7 @@ add(1, 2) # expect a result of 3
The next function takes an input name and returns a string containing a welcome phrase.
```python
+
def welcome(name):
welcome_phrase = "Hello, " + name + "!"
print(welcome_phrase)
@@ -85,6 +92,7 @@ Python has a number of different data structures for storing and manipulating va
A data structure that holds an ordered collection (sequence) of items.
```python
+
networks = ['lora', 'sigfox', 'wifi', 'bluetooth', 'lte-m']
print(networks[2]) # expect 'wifi'
```
@@ -94,6 +102,7 @@ print(networks[2]) # expect 'wifi'
A dictionary is like an address-book where you can find the address or contact details of a person by knowing only his/her name, i.e. keys (names) are associate with values (details).
```python
+
address_book = {'Alex':'2604 Crosswind Drive','Joe':'1301 Hillview Drive','Chris':'3236 Goldleaf Lane'}
print(address_book['Alex']) # expect '2604 Crosswind Drive'
```
@@ -103,6 +112,7 @@ print(address_book['Alex']) # expect '2604 Crosswind Drive'
Similar to lists but are immutable, i.e. you cannot modify tuples after instantiation.
```python
+
pycom_devices = ('wipy', 'lopy', 'sipy', 'gpy', 'fipy')
print(pycom_devices[0]) # expect 'wipy'
```
diff --git a/content/gettingstarted/programming/first-project.md b/content/gettingstarted/programming/first-project.md
index 40ece37..3b2c92d 100644
--- a/content/gettingstarted/programming/first-project.md
+++ b/content/gettingstarted/programming/first-project.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/programming/first-project.md
- chapter/gettingstarted/programming/first-project
---
+
This guide will take you through how to setup your first project with Pymakr and make the on-board RGB LED flash various colours.
## Creating a project in Pymakr
@@ -27,7 +28,7 @@ If you are using Atom, it is important to check at this point that Atom has succ
If this is not the case you can press `alt-ctrl-r` on Windows/Linux or `ctrl-alt-cmd-l` on macOS, in order to reload Atom and fix the issue.
{{< /hint >}}
-1. Now that you have a project created, we need to add some files to it. A standard MicroPython project has the following structure:
+4. Now that you have a project created, we need to add some files to it. A standard MicroPython project has the following structure:
```text
RGB-Blink
@@ -39,7 +40,7 @@ RGB-Blink
* `boot.py` This is the first script that runs on your module when it
- turns on. This is often used to connect a module a a WiFi network so that
+ turns on. This is often used to connect a module to a WiFi network so that
Telnet and FTP can be used without connecting to the WiFi AP created by the
@@ -65,13 +66,14 @@ RGB-Blink
For this example, you will just need to create a `main.py` file.
-Now that the project structure is setup, you may wish to configure project specific settings for Pymakr e.g. Which serial port to use. On Atom you need to click the `^` button on the Pymakr pane, then click `Project Settings`. On Visual Studio Code you need to click the `All commands` button on the bottom of the windows, then click `Pymakr > Project Settings`. This creates a file called `pymakr.conf` inside your project and populates it with default settings copied over from your global settings. A detailed explanation of these settings can be found [here](/../pymakr/settings).
+Now that the project structure is setup, you may wish to configure project specific settings for Pymakr e.g. Which serial port to use. On Atom you need to click the `^` button on the Pymakr pane, then click `Project Settings`. On Visual Studio Code you need to click the `All commands` button on the bottom of the windows, then click `Pymakr > Project Settings`. This creates a file called `pymakr.conf` inside your project and populates it with default settings copied over from your global settings. A detailed explanation of these settings can be found [here](/pymakr/settings).
## Controlling the on-board LED
-Now that you have setup and configured your project, we can move on to programming your module. The first thing we will need to do is import some libraries in order to interact with the on-board LED. The Pycom firmware comes with a large amount of libraries for standard functionality built-in. You can find out more about these in the [API documentation](/../firmwareapi/introduction). For this example you will need to open the `main.py` file and add the following code:
+Now that you have setup and configured your project, we can move on to programming your module. The first thing we will need to do is import some libraries in order to interact with the on-board LED. The Pycom firmware comes with a large amount of libraries for standard functionality built-in. You can find out more about these in the [API documentation](/firmwareapi/introduction). For this example you will need to open the `main.py` file and add the following code:
```python
+
import pycom
import time
```
@@ -81,6 +83,7 @@ This will import two libraries, `Pycom` which is responsible for Pycom specific
You may have noticed that when you power up your Pycom module, the on-board LED blinks blue on a regular basis. This "heartbeat" is used as a way of know that your module has powered up and started correctly. Before we can change the colour of this LED we need to disable this heart beat. Below your imports you will need to add the following:
```python
+
pycom.heartbeat(False)
```
@@ -89,6 +92,7 @@ Now it's time to test your code. On the Pymakr pane/bottom of the window you wil
Now that we can confirm the device is connected and Pymakr is able to run code on it, we can complete our script to blink the LED like so:
```python
+
import pycom
import time
@@ -112,7 +116,7 @@ In the previous section we got code running on on your Pycom module using the `r
If you need to remove files from your device you have two options, either connect via FTP and manage your files that way or format the device's internal flash like so:
```python
+
import os
os.mkfs('/flash')
```
-
diff --git a/content/gettingstarted/programming/ftp.md b/content/gettingstarted/programming/ftp.md
index a3369a9..bb589d5 100644
--- a/content/gettingstarted/programming/ftp.md
+++ b/content/gettingstarted/programming/ftp.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/programming/ftp.md
- chapter/gettingstarted/programming/ftp
---
+
There is a small internal file system accessible with each Pycom device, called `/flash`. This is stored within the external serial flash memory. If a microSD card is also connected and mounted, it will be available as well. When the device starts up, it will always boot from the `boot.py` located in the `/flash` file system.
The file system is accessible via the native FTP server running on each Pycom device. Open an FTP client and connect to:
@@ -13,7 +14,7 @@ The file system is accessible via the native FTP server running on each Pycom de
* username: `micro`
* password: `python`
-See [network.server](/../firmwareapi/pycom/network/server) for information on how to change the defaults. The recommended clients are:
+See [network.server](/firmwareapi/pycom/network/server) for information on how to change the defaults. The recommended clients are:
* macOS/Linux: default FTP client
* Windows: Filezilla and FireFTP
diff --git a/content/gettingstarted/programming/micropython.md b/content/gettingstarted/programming/micropython.md
index eec943f..fd6f5e4 100644
--- a/content/gettingstarted/programming/micropython.md
+++ b/content/gettingstarted/programming/micropython.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/programming/micropython.md
- chapter/gettingstarted/programming/micropython
---
+
Our boards work with [MicroPython](https://micropython.org/); a Python 3.5 implementation that is optimised to run on micro controllers. This allows for much faster and more simple development process than using C.

diff --git a/content/gettingstarted/programming/repl/README.md b/content/gettingstarted/programming/repl/README.md
index c18668e..fa5084f 100644
--- a/content/gettingstarted/programming/repl/README.md
+++ b/content/gettingstarted/programming/repl/README.md
@@ -3,6 +3,7 @@ title: "REPL"
aliases:
- chapter/gettingstarted/programming/repl
---
+
REPL stands for Read Evaluate Print Loop, and is the name given to the interactive MicroPython prompt that is accessible on the Pycom devices. Using the REPL is by far the easiest way to test out Python code and run commands. You can use the REPL in addition to writing scripts in `main.py`.
The following pages will explain how to use the REPL with both Serial USB and Telnet connections.
diff --git a/content/gettingstarted/programming/repl/_index.md b/content/gettingstarted/programming/repl/_index.md
index bf88ccb..5107c77 100644
--- a/content/gettingstarted/programming/repl/_index.md
+++ b/content/gettingstarted/programming/repl/_index.md
@@ -2,6 +2,7 @@
title: "REPL"
aliases:
---
+
REPL stands for Read Evaluate Print Loop, and is the name given to the interactive MicroPython prompt that is accessible on the Pycom devices. Using the REPL is by far the easiest way to test out Python code and run commands. You can use the REPL in addition to writing scripts in `main.py`.
The following pages will explain how to use the REPL with both Serial USB and Telnet connections.
diff --git a/content/gettingstarted/programming/repl/serial.md b/content/gettingstarted/programming/repl/serial.md
index d51ef5a..7ecd830 100644
--- a/content/gettingstarted/programming/repl/serial.md
+++ b/content/gettingstarted/programming/repl/serial.md
@@ -5,13 +5,14 @@ aliases:
- gettingstarted/programming/repl/serial.md
- chapter/gettingstarted/programming/repl/serial
---
-To use the REPL, a Pycom device must be connected to the host computer with a USB connection either to an Expansion Board or to serial converter (a diagram of how to do this can be found the the [getting started](/../introduction) page for your module).
+
+To use the REPL, a Pycom device must be connected to the host computer with a USB connection either to an Expansion Board or to serial converter (a diagram of how to do this can be found the the [getting started](../../../introduction) page for your module).
In order to connect to the REPL over USB serial, there are multiple methods. Detailed below are the explanations of how to do it in MacOS, Linux and Windows.
## All platforms
-By far the easiest way to access the USB UART REPL is via the our [Pymakr plug-in](/../../pymakr/installation/) for Atom and Visual Studio Code. This adds a pane to the bottom of the editors that allows you to directly access the REPL and any output from the device. Detailed instructions on how to setup Pymakr can be found [here](/../../pymakr/installation/).
+By far the easiest way to access the USB UART REPL is via the our [Pymakr plug-in](/pymakr/installation/) for Atom and Visual Studio Code. This adds a pane to the bottom of the editors that allows you to directly access the REPL and any output from the device. Detailed instructions on how to setup Pymakr can be found [here](/pymakr/installation/).
## macOS and Linux
@@ -55,5 +56,4 @@ To use PuTTY the serial port (COM port) in which the Pycom device is connected,
3. Finally, click the `Open` button
-
-
+
diff --git a/content/gettingstarted/programming/repl/telnet.md b/content/gettingstarted/programming/repl/telnet.md
index 8b9dc8b..bd389d0 100644
--- a/content/gettingstarted/programming/repl/telnet.md
+++ b/content/gettingstarted/programming/repl/telnet.md
@@ -5,7 +5,8 @@ aliases:
- gettingstarted/programming/repl/telnet.md
- chapter/gettingstarted/programming/repl/telnet
---
-Pycom devices also support a connection via `telnet`, using the device's on board WiFi/WLAN. Connect to the device's WiFi Access Point (AP) and using the following credentials to connect to the AP. The WiFi `SSID` will appear upon powering on a Pycom Device for the first time (e.g. `lopy-`). To re-enable this feature at a later date, please see [network.WLAN]().
+
+Pycom devices also support a connection via `telnet`, using the device's on board WiFi/WLAN. Connect to the device's WiFi Access Point (AP) and using the following credentials to connect to the AP. The WiFi `SSID` will appear upon powering on a Pycom Device for the first time (e.g. `lopy-`). To re-enable this feature at a later date, please see [network.WLAN](/firmwareapi/pycom/network/wlan).
* password: `www.pycom.io`
@@ -16,11 +17,11 @@ Additionally, to use the MircoPython REPL over telnet, further authentication is
* username: `micro`
* password: `python`
-See [network.server](/../../firmwareapi/pycom/network/server) for info on how to change the default authentication.
+See [network.server](/firmwareapi/pycom/network/server) for info on how to change the default authentication.
## All platforms
-By far the easiest way to access the Telnet REPL is via the our [Pymakr plug-in](/../../pymakr/installation/) for Atom and Visual Studio Code. This adds a pane to the bottom of the editors that allows you to directly access the REPL and any output from the device. Detailed instructions on how to setup Pymakr can be found [here](/../../pymakr/installation/).
+By far the easiest way to access the Telnet REPL is via the our [Pymakr plug-in](/pymakr/installation/) for Atom and Visual Studio Code. This adds a pane to the bottom of the editors that allows you to directly access the REPL and any output from the device. Detailed instructions on how to setup Pymakr can be found [here](/pymakr/installation/).
## macOS and Linux
@@ -43,4 +44,3 @@ A terminal emulator is needed to open a telnet connection from Windows; the easi
{{% hint style="info" %}}
When using a Pycom device with a personal, home or office WiFi access point, the telnet connection may still be used. In this instance, the user will need to determine the Pycom device's local IP address and substitute this for `192.168.4.1`, referred to in the earlier sections.
{{< /hint >}}
-
diff --git a/content/gettingstarted/programming/safeboot.md b/content/gettingstarted/programming/safeboot.md
index 3b0116b..ab2cef1 100644
--- a/content/gettingstarted/programming/safeboot.md
+++ b/content/gettingstarted/programming/safeboot.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/programming/safeboot.md
- chapter/gettingstarted/programming/safeboot
---
+
If powering up normally or upon pressing the reset button, a Pycom module will boot into standard mode; the `boot.py` file will be executed first, followed by `main.py`. It is possible to alter the boot procedure of the module by tying certain pins `high` or `low` when the module boots.
## Bootloader
@@ -32,6 +33,7 @@ The selection made during safe boot is not persistent, therefore after the next
If problems occur within the filesystem or you wish to factory reset your module to remove your code, run following code in the REPL:
```python
+
>>> import os
>>> os.mkfs('/flash')
```
@@ -45,6 +47,7 @@ Be aware, resetting the flash filesystem will delete all files inside the intern
Pycom devices support both soft and hard resets. A soft reset clears the state of the MicroPython virtual machine but leaves hardware peripherals unaffected. To do a soft reset, press `Ctrl+D` on the REPL or from within a script, run:
```python
+
>>> import sys
>>> sys.exit()
```
@@ -52,6 +55,7 @@ Pycom devices support both soft and hard resets. A soft reset clears the state o
A hard reset is the same as performing a power cycle to the device. In order to hard reset the device, press the `reset` switch or run:
```python
+
>>> import machine
>>> machine.reset()
```
diff --git a/content/gettingstarted/registration/_index.md b/content/gettingstarted/registration/_index.md
index aad0d36..37cb7bb 100644
--- a/content/gettingstarted/registration/_index.md
+++ b/content/gettingstarted/registration/_index.md
@@ -2,6 +2,7 @@
title: "Device Registration"
aliases:
---
+
Some of our devices require registration before you can utilise specific features such as certain types of networking. Please see the list below for setup guides to ensure that your device is registered and activated on the various platforms required to access all of the available features.
[](sigfox)
diff --git a/content/gettingstarted/registration/cellular.md b/content/gettingstarted/registration/cellular.md
index c59c9fb..7661d4f 100644
--- a/content/gettingstarted/registration/cellular.md
+++ b/content/gettingstarted/registration/cellular.md
@@ -5,6 +5,7 @@ aliases:
- gettingstarted/registration/cellular.md
- chapter/gettingstarted/registration/cellular
---
+
In order to use your GPy/FiPy on a cellular network you are required to get a SIM card from a local provider.
_Note: This might differ from a standard SIM you can buy in a store, our devices do not support standard LTE._
diff --git a/content/gettingstarted/registration/lora/_index.md b/content/gettingstarted/registration/lora/_index.md
index 497c89d..cc20a04 100644
--- a/content/gettingstarted/registration/lora/_index.md
+++ b/content/gettingstarted/registration/lora/_index.md
@@ -2,6 +2,7 @@
title: "LoRaWAN"
aliases:
---
+
## Raw LoRa
When using raw LoRa, you do not have to register your module in any way. The modules can talk to each other directly.
@@ -15,6 +16,8 @@ In order to connect your LoRa capable Pycom module to a LoRaWAN network you will
Firstly you will need to get your modules `Device EUI`, this can be achieved using the following code:
```python
+
+
from network import LoRa
import ubinascii
@@ -26,19 +29,18 @@ The output will be a hex string like: `70B3D5499585FCA1`. Once you have this you
#### OTAA
-If you wish to connect via OTAA (which is the recommended method) the network will provide you with an `Application EUI` and `Application Key`. The former identifies what application your device is connecting to, the latter is a shared secret key unique to your device to generate the session keys that prove its identity to the network. Once you have these you can use the [LoRaWAN OTAA example](/../../tutorials/lora/lorawan-otaa) code to connect to the network.
+If you wish to connect via OTAA (which is the recommended method) the network will provide you with an `Application EUI` and `Application Key`. The former identifies what application your device is connecting to, the latter is a shared secret key unique to your device to generate the session keys that prove its identity to the network. Once you have these you can use the [LoRaWAN OTAA example](/tutorials/lora/lorawan-otaa) code to connect to the network.
#### ABP
-With ABP the encryption keys enabling communication with the network are preconfigured in the device. The network will need to provide you with a `Device Address`, `Network Session Key` and `Application Session Key`. Once you have these you can use the [LoRaWAN ABP example](/../../tutorials/lora/lorawan-abp) code to connect to the network.
+With ABP the encryption keys enabling communication with the network are preconfigured in the device. The network will need to provide you with a `Device Address`, `Network Session Key` and `Application Session Key`. Once you have these you can use the [LoRaWAN ABP example](/tutorials/lora/lorawan-abp) code to connect to the network.
### Networks
-[](ttn)
+ [](ttn)
-[](objenious)
+ [](senet)
{{% hint style="info" %}}
If you cannot find your favourite LoRaWAN network in the list above, please consider writing a tutorial for how to connect a Pycom module with it and contribute it to this documentation via a [GitHub pull request](https://github.com/pycom/pycom-documentation).
{{< /hint >}}
-
diff --git a/content/gettingstarted/registration/lora/senet.md b/content/gettingstarted/registration/lora/senet.md
new file mode 100644
index 0000000..dc19583
--- /dev/null
+++ b/content/gettingstarted/registration/lora/senet.md
@@ -0,0 +1,83 @@
+---
+title: "Senet"
+aliases:
+ - gettingstarted/registration/lora/senet.html
+ - gettingstarted/registration/lora/senet.md
+---
+
+
+
+## The Senet Developer Portal
+
+Connecting your device begins by creating an account on the Senet Developer Portal. This will grant you free access for up to 10 devices and 5 gateways to support application development activities. [Sign-Up](https://portal.senetco.io/)
+
+Complete Senet Developer Portal documentation is available on line at [Docs](https://docs.senetco.io/docs).
+
+Once your account has been activated, you may want to onboard a gateway, if Senet public network access in unavailable. Onboarding your device consists of registering the device through your portal account and then provisioning your device with the information provided at the completion of the registration process. Senet supports both Over-The-Air-Activation (OTAA) and Activation-By-Personalization (ABP). As ABP is useful only in a very narrow set of use-cases, this tutorial will walk you through OTAA registration and provisioning.
+
+## Device Identity and Security Elements
+
+All LoRaWAN 1.0.x end-devices require three provisioning elements to join a network. Devices typically come from the factory with a unique, 64-bit EUI (called a DevEUI) which is the device's globally unique identifier. In the case of the Senet Developer Portal, the two additional elements (The Application EUI or AppEUI and Application Key or AppKey) will be generated and provided to you after registration (in typical production environments, these additional elements are also provided during manufacturing and provisioned into the network backend).
+
+* Device EUI (DevEUI)
+* Application EUI (AppEUI)
+* Application Key (AppKey)
+
+### Device EUI
+
+This comes from the device itself and can be obtained from `lora.mac()`.
+To obtain the required hexadecimal representation you can run the following code on your LoPy:
+
+```python
+
+from network import LoRa
+import ubinascii
+
+lora = LoRa()
+print("DevEUI: %s" % (ubinascii.hexlify(lora.mac()).decode('ascii')))
+```
+
+Use this value during the first step of device registration.
+
+
+
+### Application EUI and Application Key
+
+The Application EUI uniquely identifies the security broker (called a Join Server in LoRaWAN terminology) which is interogated by the network when the device attempts to join the network. The Application Key is the shared secret (between the end-device and the Join-Server) which forms the basis for LoRaWAN security and is used to generate the application and network session keys used for privacy and message integrity.
+
+At the completion of your device registration process on the Senet Developer Portal, you will be presented with the Application EUI and the Application Key which you will need to provision in your device. This information is always available after the fact in the device details screen.
+
+
+
+## Provisioning the LoPy or FiPy
+
+After device registration is complete, configure the device for optimal operation and provision the AppEUI and AppKey.
+
+```python
+
+from network import LoRa
+import socket
+import time
+import ubinascii
+
+# Initialise LoRa in LORAWAN mode.
+# Please pick the region that matches where you are using the device:
+# Asia = LoRa.AS923
+# Australia = LoRa.AU915
+# Europe = LoRa.EU868
+# United States = LoRa.US915
+lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.US915)
+
+# create an OTAA authentication parameters
+app_eui = ubinascii.unhexlify('00250C0000010001')
+app_key = ubinascii.unhexlify('00112233445566778899AABBCCDDEEFF')
+
+# initialize LoRa
+lora.init(mode=LoRa.LORAWAN, adr=True, public=True)
+
+# join a network using OTAA (Over the Air Activation)
+lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), dr=0, timeout=0)
+```
+
+You are now ready to start sending messages from your device! Each device may be provisioned to stream the datagrams to the backend service of your choice in a variety of standard and custom formats.
+
diff --git a/content/gettingstarted/registration/lora/ttn.md b/content/gettingstarted/registration/lora/ttn.md
index 0bfd471..88f0821 100644
--- a/content/gettingstarted/registration/lora/ttn.md
+++ b/content/gettingstarted/registration/lora/ttn.md
@@ -5,9 +5,10 @@ aliases:
- gettingstarted/registration/lora/ttn.md
- chapter/gettingstarted/registration/lora/ttn
---
+
In order to use The Things Network (TTN) you should navigate to their website and create/register an account. Enter a username and an email address to verify with their platform.
-
+
Once an account has been registered, you can register your Pycom module as either a node or a nano-gateway. The steps below will detail how to do this.
@@ -17,7 +18,7 @@ In order to register your device to connect to the things network, you must firs
Selecting the `Applications` tab at the top of the TTN console, will bring up a screen for registering applications. Click register and a new page, similar to the one below, will open.
-
+
Enter a unique `Application ID` as well as a Description & Handler Registration.
@@ -27,11 +28,12 @@ Now the Pycom module nodes can be registered to send data up to the new Applicat
To connect nodes to a things network gateway, devices need to be added to the application. To do this, navigate to the `Devices` tab on the `Application` home page and click the `Register Device` button.
-
+
In the `Register Device` panel, complete the forms for the `Device ID` and the `Device EUI`. The `Device ID` is user specified and is unique to the device in this application. The `Device EUI` should be a globally unique identifier for the device. You can run the following on you Pycom module to retrieve its EUI.
```python
+
from network import LoRa
import ubinascii
@@ -43,15 +45,15 @@ Once the device has been added, change the `Activation Method` between `OTAA` an
## Register a Nano-Gateway
-You can also setup your Pycom module to act as a gateway with The Things Network. The code required to do this can be found [here](/../../tutorials/lora/lorawan-nano-gateway).
+You can also setup your Pycom module to act as a gateway with The Things Network. The code required to do this can be found [here](/tutorials/lora/lorawan-nano-gateway).
Inside the TTN Console, there are two options, `Applications` and `Gateways`. Select `Gateways` and then click on `register Gateway`. This will allow for the set up and registration of a new nano-gateway.
-
+
On the Register Gateway page, you will need to set the following settings:
-
+
These are unique to each gateway, location and country specific frequency. Please verify that correct settings are selected otherwise the gateway will not connect to TTN.
@@ -69,6 +71,7 @@ These are unique to each gateway, location and country specific frequency. Pleas
Most LoRaWAN network servers expect a Gateway ID in the form of a unique 64-bit hexadecimal number (called a EUI-64). The recommended practice is to produce this ID from your board by expanding the WiFi MAC address (a 48-bit number, called MAC-48). You can obtain that by running this code prior to configuration:
```python
+
from network import WLAN
import binascii
wl = WLAN()
@@ -77,7 +80,6 @@ Most LoRaWAN network servers expect a Gateway ID in the form of a unique 64-bit
Once these settings have been applied, click `Register Gateway`. A Gateway Overview page will appear, with the configuration settings showing. Next click on the `Gateway Settings` and configure the Router address to match that of the gateway (default: `router.eu.thethings.network`).
-
+
The `Gateway` should now be configured.
-
diff --git a/content/gettingstarted/registration/sigfox.md b/content/gettingstarted/registration/sigfox.md
index 73c53a6..628b887 100644
--- a/content/gettingstarted/registration/sigfox.md
+++ b/content/gettingstarted/registration/sigfox.md
@@ -5,17 +5,25 @@ aliases:
- gettingstarted/registration/sigfox.md
- chapter/gettingstarted/registration/sigfox
---
+
Before you start, update your device to the latest firmware. Select _stable_ firmware in Firmware updater. After firmware update is done, _Sigfox ID_ and _Sigfox PAC_ were assigned to your device.
Copy _Sigfox ID_ and _Sigfox PAC_ from the last screen of firmware updater.

-_Sigfox ID_ and _Sigfox Pac_ is assigned to your device just once during the first update process. _Sigfox ID_ and _Sigfox Pac_ will not change after successive firmware updates.
+{{% hint style="danger" %}}
+_Sigfox ID_ and _Sigfox Pac_ are assigned to your device just once during the first firmware update process. They will not change after successive firmware updates.
+Sigfox Pac is one-time activation code, which will be invalidated after device's registration on Sigfox Backend.
+Keep in mind that firmware updater will always display the same (even invalid) Sigfox Pac.
+In case of successive registration to a new account (or device type) on Sigfox Backend, you need to get Sigfox Pac from device page on Sigfox Backend.
+See [Sigfox documentation](https://support.sigfox.com/docs/device-idpac-couple) for more info.
+{{< /hint >}}
After first firmware update you can also get your _Sigfox ID_ and _Sigfox PAC_ through a couple of commands via the REPL.
```python
+
from network import Sigfox
import binascii
@@ -72,4 +80,3 @@ Now you can see your new Sigfox PAC.

Once you know your new Sigfox PAC go to [https://backend.sigfox.com/activate](https://backend.sigfox.com/activate) and register device with different account.
-
diff --git a/content/gettingstarted/troubleshooting-guide.md b/content/gettingstarted/troubleshooting-guide.md
new file mode 100644
index 0000000..85659c0
--- /dev/null
+++ b/content/gettingstarted/troubleshooting-guide.md
@@ -0,0 +1,104 @@
+---
+title: "Troubleshooting Guide"
+aliases:
+ - gettingstarted/troubleshooting-guide.html
+ - gettingstarted/troubleshooting-guide.md
+---
+
+## How to ask for help
+
+Always provide these details when asking for help. This helps us understand your setup and save time.
+
+* Run `os.uname()` on your module to get the version numbers
+* Your module's type & version (e.g. FiPy 1.0)
+* Any shields, or devices connected (e.g. Pytrack, Extension Board 3.0 with “x" sensor)
+* Your Operating System's version
+* Pymakr version
+* Atom / VSCode version
+* Have you looked at our [documentation](https://docs.pycom.io) and similar issues on the [forum](https://forum.pycom.io)?
+
+## Firmware Update
+
+#### Firmware file has unexpected sha1 checksum.
+
+If you're trying to update to the latest `development` firmware, make sure you use the development release of the Firmware Updater.
+
+#### My module is recognised as the wrong type
+
+Open a support ticket with the details and send us the result of this code:
+
+```python
+
+import machine, binascii
+binascii.hexlify(machine.unique_id())
+```
+
+## Connecting to the module
+
+#### Module stuck in bootloader mode
+
+Normally, the firmware updater switches back to application mode at the end of an upgrade. If that doesn't happen for some reason, re-plugging the USB cable also puts the device back into application mode.
+
+## Pymakr
+
+Make sure you have the latest version of Pymakr and [Atom](https://atom.io)/[VSCode](https://code.visualstudio.com) installed.
+
+**Synchronising a project results in ‘Failed to allocate memory' error**
+
+Synchronising takes a bit of memory, so this error can occur when code running on the board already is taking a substantial amount of memory.
+
+**Solution:** use safe boot with [REPL](https://docs.pycom.io/gettingstarted/programming/repl) or [Expansion Board](https://docs.pycom.io/product-info/boards/expansion3) when synchronising
+
+### Atom
+
+**Failed to load package: Cannot find module ‘serialport'**
+
+In some cases, this is caused by the Atom Package Manager (apm) using Python 3.x, while `node-gyp` (used for compiling the `serialport` lib) needs Python 2.x. To confirm this, `apm —version` can be run to check which Python version apm is using.
+
+**Solution:** Tell the package manager to use python 2 instead. Running the following command switches apm to 2.7:
+
+```text
+echo “python=/usr/bin/python2.7” >> ~/.atom/.apmrc
+```
+
+Now reinstall Pymakr or run apm install from the Pymakr package located in `~/.atom/packages/pymakr`
+
+**Could not locate the bindings file**
+
+If the installation of the `serialport` library failed, it reverts back to the precompiled version that is included in the plugin. This is compiled for the latest versions of Atom and loses compatibility with older versions.
+
+**Solution:** upgrade to the latest Atom (1.19.0 or higher) or install the previous version of the plugin (`apm install pymakr@1.0.3`)
+
+**Any error where the traceback contains \.atom\packages\Pymakr\ with a capital “P”**
+
+This happened after `Pymakr` renamed to `pymakr` (lowercase) starting at version 1.2.5, but Atom remembers the old folder name inside the packages folder.
+
+**Solution:**
+
+* Uninstall Pymakr
+* Remove folder: `~/.atom/.apm/Pymkr`
+* Empty folder: `~/.config/Atom/Cache`
+* Reinstall pymakr
+
+**Cannot connect to Pycom board via REPL**
+
+In the case of a board that has already has code uploaded to it and is running a loop/non-exiting script, the board may not boot into a REPL.
+
+**Solution:** If the board is currently running code, you will need to exit the current script before proceeding: 1. Ensure your board is connected to your computer 2. Press the reset button on the device 3. Press `ctrl-c` on within the Pymakr console to exit the current script/program
+
+The REPL should then appear with the `>>>` prompt and you will be able to run/sync your code.
+
+**Cannot connect to Pycom on Linux**
+
+If you're a Linux user and can't connect to your board, there might be a permission issue to access the serial port.
+
+**Solution:** Run the following command `sudo usermod -a -G dialout $USER`
+
+### VSCode
+
+**Terminal not opening**
+
+If the Pymakr terminal is not opening or giving an error, this might be because NodeJS is not installed on your system. This is because the terminal process is running separate from VSCode and depends on your systems NodeJS install.
+
+**Solution:** install NodeJS. For Windows 64 machines, install a 32 bit version of NodeJS (for example `nvm install 7.8.0 32` when using `nvm`).
+
diff --git a/content/gitbook/fonts/fontawesome/FontAwesome.otf b/content/gitbook/fonts/fontawesome/FontAwesome.otf
new file mode 100644
index 0000000..d4de13e
Binary files /dev/null and b/content/gitbook/fonts/fontawesome/FontAwesome.otf differ
diff --git a/content/gitbook/fonts/fontawesome/fontawesome-webfont.eot b/content/gitbook/fonts/fontawesome/fontawesome-webfont.eot
new file mode 100644
index 0000000..3fa29c2
Binary files /dev/null and b/content/gitbook/fonts/fontawesome/fontawesome-webfont.eot differ
diff --git a/content/gitbook/fonts/fontawesome/fontawesome-webfont.svg b/content/gitbook/fonts/fontawesome/fontawesome-webfont.svg
new file mode 100644
index 0000000..8b66187
--- /dev/null
+++ b/content/gitbook/fonts/fontawesome/fontawesome-webfont.svg
@@ -0,0 +1,685 @@
+
+
+
\ No newline at end of file
diff --git a/content/gitbook/fonts/fontawesome/fontawesome-webfont.ttf b/content/gitbook/fonts/fontawesome/fontawesome-webfont.ttf
new file mode 100644
index 0000000..f221e50
Binary files /dev/null and b/content/gitbook/fonts/fontawesome/fontawesome-webfont.ttf differ
diff --git a/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff b/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff
new file mode 100644
index 0000000..567a49c
Binary files /dev/null and b/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff differ
diff --git a/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 b/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff2
new file mode 100644
index 0000000..3d43adf
Binary files /dev/null and b/content/gitbook/fonts/fontawesome/fontawesome-webfont.woff2 differ
diff --git a/content/gitbook/gitbook-plugin-algolia/algolia-logo.jpg b/content/gitbook/gitbook-plugin-algolia/algolia-logo.jpg
new file mode 100644
index 0000000..7b5e09c
Binary files /dev/null and b/content/gitbook/gitbook-plugin-algolia/algolia-logo.jpg differ
diff --git a/content/gitbook/gitbook-plugin-algolia/plugin-algolia.css b/content/gitbook/gitbook-plugin-algolia/plugin-algolia.css
new file mode 100644
index 0000000..ae46c18
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-algolia/plugin-algolia.css
@@ -0,0 +1,12 @@
+.powered-by-algolia {
+ margin-top: 30px;
+ text-align: right;
+ opacity: 0.75;
+
+ color: #555;
+ font-size: 13px;
+}
+
+.powered-by-algolia img {
+ vertical-align: bottom;
+}
\ No newline at end of file
diff --git a/content/gitbook/gitbook-plugin-algolia/search-algolia.js b/content/gitbook/gitbook-plugin-algolia/search-algolia.js
new file mode 100644
index 0000000..43d2442
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-algolia/search-algolia.js
@@ -0,0 +1,49 @@
+require([
+ 'gitbook',
+ 'jquery'
+], function(gitbook, $) {
+ // Define algolia search engine
+ function AlgoliaSearchEngine(config) {
+ // Create algolia client
+ // eslint-disable-next-line no-undef
+ this.client = algoliasearch(config.algolia.applicationID, config.algolia.publicKey);
+ this.index = this.client.initIndex(config.algolia.index);
+ this.name = 'AlgoliaSearchEngine';
+ }
+
+ AlgoliaSearchEngine.prototype.init = function() {
+ return $.Deferred().resolve().promise();
+ };
+
+ AlgoliaSearchEngine.prototype.search = function(q, offset, length) {
+ var d = $.Deferred();
+
+ this.index.search(q, { hitsPerPage: length })
+ .then(function(res) {
+ // return content;
+ var results = res.hits.map(function(hit) {
+ return {
+ title: hit.title,
+ body: hit['_highlightResult'].body.value,
+ url: hit.url
+ };
+ });
+
+ d.resolve({
+ query: res.query,
+ count: res.nbHits,
+ results: results
+ });
+ })
+ .catch(function(err) {
+ d.reject(err);
+ });
+
+ return d.promise();
+ };
+
+ gitbook.events.bind('start', function(e, config) {
+ // Set gitbook research to Algolia
+ gitbook.search.setEngine(AlgoliaSearchEngine, config);
+ });
+});
\ No newline at end of file
diff --git a/content/gitbook/gitbook-plugin-anchors/plugin.css b/content/gitbook/gitbook-plugin-anchors/plugin.css
new file mode 100644
index 0000000..adf3e9e
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-anchors/plugin.css
@@ -0,0 +1,30 @@
+
+a.plugin-anchor {
+ color: inherit !important;
+ display: none;
+ margin-left: -30px;
+ padding-left: 40px;
+ cursor: pointer;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+}
+
+a.plugin-anchor i {
+ margin-left: -30px;
+ font-size: 15px !important;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ position: relative;
+}
+
+h1:hover a.plugin-anchor, h2:hover a.plugin-anchor, h3:hover a.plugin-anchor,
+h4:hover a.plugin-anchor, h5:hover a.plugin-anchor, h6:hover a.plugin-anchor {
+ display: inline-block;
+}
+
+.book .book-body .page-wrapper .page-inner section.normal {
+ overflow: visible;
+}
diff --git a/content/gitbook/gitbook-plugin-github/plugin.js b/content/gitbook/gitbook-plugin-github/plugin.js
new file mode 100644
index 0000000..14810ce
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-github/plugin.js
@@ -0,0 +1,14 @@
+require([ 'gitbook' ], function (gitbook) {
+ gitbook.events.bind('start', function (e, config) {
+ var githubURL = config.github.url;
+
+ gitbook.toolbar.createButton({
+ icon: 'fa fa-github',
+ label: 'GitHub',
+ position: 'right',
+ onClick: function() {
+ window.open(githubURL)
+ }
+ });
+ });
+});
diff --git a/content/gitbook/gitbook-plugin-highlight/ebook.css b/content/gitbook/gitbook-plugin-highlight/ebook.css
new file mode 100644
index 0000000..cecaaab
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-highlight/ebook.css
@@ -0,0 +1,135 @@
+pre,
+code {
+ /* http://jmblog.github.io/color-themes-for-highlightjs */
+ /* Tomorrow Comment */
+ /* Tomorrow Red */
+ /* Tomorrow Orange */
+ /* Tomorrow Yellow */
+ /* Tomorrow Green */
+ /* Tomorrow Aqua */
+ /* Tomorrow Blue */
+ /* Tomorrow Purple */
+}
+pre .hljs-comment,
+code .hljs-comment,
+pre .hljs-title,
+code .hljs-title {
+ color: #8e908c;
+}
+pre .hljs-variable,
+code .hljs-variable,
+pre .hljs-attribute,
+code .hljs-attribute,
+pre .hljs-tag,
+code .hljs-tag,
+pre .hljs-regexp,
+code .hljs-regexp,
+pre .hljs-deletion,
+code .hljs-deletion,
+pre .ruby .hljs-constant,
+code .ruby .hljs-constant,
+pre .xml .hljs-tag .hljs-title,
+code .xml .hljs-tag .hljs-title,
+pre .xml .hljs-pi,
+code .xml .hljs-pi,
+pre .xml .hljs-doctype,
+code .xml .hljs-doctype,
+pre .html .hljs-doctype,
+code .html .hljs-doctype,
+pre .css .hljs-id,
+code .css .hljs-id,
+pre .css .hljs-class,
+code .css .hljs-class,
+pre .css .hljs-pseudo,
+code .css .hljs-pseudo {
+ color: #c82829;
+}
+pre .hljs-number,
+code .hljs-number,
+pre .hljs-preprocessor,
+code .hljs-preprocessor,
+pre .hljs-pragma,
+code .hljs-pragma,
+pre .hljs-built_in,
+code .hljs-built_in,
+pre .hljs-literal,
+code .hljs-literal,
+pre .hljs-params,
+code .hljs-params,
+pre .hljs-constant,
+code .hljs-constant {
+ color: #f5871f;
+}
+pre .ruby .hljs-class .hljs-title,
+code .ruby .hljs-class .hljs-title,
+pre .css .hljs-rules .hljs-attribute,
+code .css .hljs-rules .hljs-attribute {
+ color: #eab700;
+}
+pre .hljs-string,
+code .hljs-string,
+pre .hljs-value,
+code .hljs-value,
+pre .hljs-inheritance,
+code .hljs-inheritance,
+pre .hljs-header,
+code .hljs-header,
+pre .hljs-addition,
+code .hljs-addition,
+pre .ruby .hljs-symbol,
+code .ruby .hljs-symbol,
+pre .xml .hljs-cdata,
+code .xml .hljs-cdata {
+ color: #718c00;
+}
+pre .css .hljs-hexcolor,
+code .css .hljs-hexcolor {
+ color: #3e999f;
+}
+pre .hljs-function,
+code .hljs-function,
+pre .python .hljs-decorator,
+code .python .hljs-decorator,
+pre .python .hljs-title,
+code .python .hljs-title,
+pre .ruby .hljs-function .hljs-title,
+code .ruby .hljs-function .hljs-title,
+pre .ruby .hljs-title .hljs-keyword,
+code .ruby .hljs-title .hljs-keyword,
+pre .perl .hljs-sub,
+code .perl .hljs-sub,
+pre .javascript .hljs-title,
+code .javascript .hljs-title,
+pre .coffeescript .hljs-title,
+code .coffeescript .hljs-title {
+ color: #4271ae;
+}
+pre .hljs-keyword,
+code .hljs-keyword,
+pre .javascript .hljs-function,
+code .javascript .hljs-function {
+ color: #8959a8;
+}
+pre .hljs,
+code .hljs {
+ display: block;
+ background: white;
+ color: #4d4d4c;
+ padding: 0.5em;
+}
+pre .coffeescript .javascript,
+code .coffeescript .javascript,
+pre .javascript .xml,
+code .javascript .xml,
+pre .tex .hljs-formula,
+code .tex .hljs-formula,
+pre .xml .javascript,
+code .xml .javascript,
+pre .xml .vbscript,
+code .xml .vbscript,
+pre .xml .css,
+code .xml .css,
+pre .xml .hljs-cdata,
+code .xml .hljs-cdata {
+ opacity: 0.5;
+}
diff --git a/content/gitbook/gitbook-plugin-highlight/website.css b/content/gitbook/gitbook-plugin-highlight/website.css
new file mode 100644
index 0000000..6674448
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-highlight/website.css
@@ -0,0 +1,434 @@
+.book .book-body .page-wrapper .page-inner section.normal pre,
+.book .book-body .page-wrapper .page-inner section.normal code {
+ /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
+ /* Tomorrow Comment */
+ /* Tomorrow Red */
+ /* Tomorrow Orange */
+ /* Tomorrow Yellow */
+ /* Tomorrow Green */
+ /* Tomorrow Aqua */
+ /* Tomorrow Blue */
+ /* Tomorrow Purple */
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-comment,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-title {
+ color: #8e908c;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-variable,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-tag,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,
+.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,
+.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,
+.book .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,
+.book .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,
+.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,
+.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,
+.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,
+.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,
+.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,
+.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {
+ color: #c82829;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-number,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-number,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-literal,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-params,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-params,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-constant {
+ color: #f5871f;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,
+.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {
+ color: #eab700;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-string,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-string,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-value,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-value,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-header,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-header,
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-addition,
+.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,
+.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {
+ color: #718c00;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,
+.book .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {
+ color: #3e999f;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-function,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-function,
+.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,
+.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,
+.book .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,
+.book .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,
+.book .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,
+.book .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,
+.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,
+.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {
+ color: #4271ae;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,
+.book .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,
+.book .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {
+ color: #8959a8;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .hljs,
+.book .book-body .page-wrapper .page-inner section.normal code .hljs {
+ display: block;
+ background: white;
+ color: #4d4d4c;
+ padding: 0.5em;
+}
+.book .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,
+.book .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,
+.book .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,
+.book .book-body .page-wrapper .page-inner section.normal code .javascript .xml,
+.book .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,
+.book .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .javascript,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .css,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .css,
+.book .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,
+.book .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {
+ opacity: 0.5;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code {
+ /*
+
+Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull
+
+*/
+ /* Solarized Green */
+ /* Solarized Cyan */
+ /* Solarized Blue */
+ /* Solarized Yellow */
+ /* Solarized Orange */
+ /* Solarized Red */
+ /* Solarized Violet */
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs {
+ display: block;
+ padding: 0.5em;
+ background: #fdf6e3;
+ color: #657b83;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-template_comment,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-template_comment,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-header,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-header,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-doctype,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-doctype,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pi,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pi,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-javadoc,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-javadoc {
+ color: #93a1a1;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-winutils,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-winutils,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .method,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .method,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-tag,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-tag,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-request,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-request,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-status,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-status,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .nginx .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .nginx .hljs-title {
+ color: #859900;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-number,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-command,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-command,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag .hljs-value,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-tag .hljs-value,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-rules .hljs-value,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-rules .hljs-value,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-phpdoc,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-phpdoc,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-hexcolor,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-hexcolor,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_url,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_url {
+ color: #2aa198;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-localvars,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-localvars,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-chunk,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-chunk,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-decorator,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-decorator,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-identifier,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-identifier,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .vhdl .hljs-literal,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .vhdl .hljs-literal,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-id,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-id,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-function,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-function {
+ color: #268bd2;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .lisp .hljs-body,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .lisp .hljs-body,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .smalltalk .hljs-number,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .smalltalk .hljs-number,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-constant,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-class .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-class .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-parent,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-parent,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .haskell .hljs-type,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .haskell .hljs-type,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_reference,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_reference {
+ color: #b58900;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor .hljs-keyword,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor .hljs-keyword,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-shebang,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-shebang,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-symbol .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-symbol .hljs-string,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .diff .hljs-change,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .diff .hljs-change,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-special,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-special,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-attr_selector,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-attr_selector,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-subst,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-subst,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-cdata,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-cdata,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .clojure .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .clojure .hljs-title,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-header {
+ color: #cb4b16;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-important,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-important {
+ color: #dc322f;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .hljs-link_label,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .hljs-link_label {
+ color: #6c71c4;
+}
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,
+.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula {
+ background: #eee8d5;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code {
+ /* Tomorrow Night Bright Theme */
+ /* Original theme - https://github.com/chriskempson/tomorrow-theme */
+ /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
+ /* Tomorrow Comment */
+ /* Tomorrow Red */
+ /* Tomorrow Orange */
+ /* Tomorrow Yellow */
+ /* Tomorrow Green */
+ /* Tomorrow Aqua */
+ /* Tomorrow Blue */
+ /* Tomorrow Purple */
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-comment,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-comment,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-title {
+ color: #969896;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-variable,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-variable,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-attribute,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-attribute,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-tag,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-tag,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-regexp,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-regexp,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-deletion,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-deletion,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-constant,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-constant,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-tag .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-tag .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-pi,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-pi,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-doctype,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-doctype,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .html .hljs-doctype,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .html .hljs-doctype,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-id,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-id,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-class,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-class,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-pseudo,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-pseudo {
+ color: #d54e53;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-number,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-number,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-preprocessor,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-preprocessor,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-pragma,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-pragma,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-built_in,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-built_in,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-literal,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-literal,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-params,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-params,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-constant,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-constant {
+ color: #e78c45;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-class .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-class .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-rules .hljs-attribute,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-rules .hljs-attribute {
+ color: #e7c547;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-string,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-string,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-value,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-value,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-inheritance,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-inheritance,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-header,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-header,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-addition,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-addition,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-symbol,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-symbol,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {
+ color: #b9ca4a;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .css .hljs-hexcolor,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .css .hljs-hexcolor {
+ color: #70c0b1;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-function,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-function,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-decorator,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-decorator,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .python .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .python .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-function .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-function .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .ruby .hljs-title .hljs-keyword,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .ruby .hljs-title .hljs-keyword,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .perl .hljs-sub,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .perl .hljs-sub,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .hljs-title,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .hljs-title {
+ color: #7aa6da;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs-keyword,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs-keyword,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .hljs-function,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .hljs-function {
+ color: #c397d8;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .hljs,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .hljs {
+ display: block;
+ background: black;
+ color: #eaeaea;
+ padding: 0.5em;
+}
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .coffeescript .javascript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .coffeescript .javascript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .javascript .xml,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .javascript .xml,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .tex .hljs-formula,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .tex .hljs-formula,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .javascript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .javascript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .vbscript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .vbscript,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .css,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .css,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal pre .xml .hljs-cdata,
+.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal code .xml .hljs-cdata {
+ opacity: 0.5;
+}
diff --git a/content/gitbook/gitbook-plugin-hints/plugin-hints.css b/content/gitbook/gitbook-plugin-hints/plugin-hints.css
new file mode 100644
index 0000000..ed4480c
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-hints/plugin-hints.css
@@ -0,0 +1,9 @@
+.hints-icon {
+ display: table-cell;
+ padding-right: 15px;
+ padding-left: 5px;
+}
+
+.hints-container {
+ display: table-cell;
+}
diff --git a/content/gitbook/gitbook-plugin-livereload/plugin.js b/content/gitbook/gitbook-plugin-livereload/plugin.js
new file mode 100644
index 0000000..923b3ae
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-livereload/plugin.js
@@ -0,0 +1,11 @@
+(function() {
+ var newEl = document.createElement('script'),
+ firstScriptTag = document.getElementsByTagName('script')[0];
+
+ if (firstScriptTag) {
+ newEl.async = 1;
+ newEl.src = '//' + window.location.hostname + ':35729/livereload.js';
+ firstScriptTag.parentNode.insertBefore(newEl, firstScriptTag);
+ }
+
+})();
diff --git a/content/gitbook/gitbook-plugin-lunr/lunr.min.js b/content/gitbook/gitbook-plugin-lunr/lunr.min.js
new file mode 100644
index 0000000..6aa6bc7
--- /dev/null
+++ b/content/gitbook/gitbook-plugin-lunr/lunr.min.js
@@ -0,0 +1,7 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 0.5.12
+ * Copyright (C) 2015 Oliver Nightingale
+ * MIT Licensed
+ * @license
+ */
+!function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.5.12",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(t){return arguments.length&&null!=t&&void 0!=t?Array.isArray(t)?t.map(function(t){return t.toLowerCase()}):t.toString().trim().toLowerCase().split(/[\s\-]+/):[]},t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.registeredFunctions[e];if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._stack.indexOf(e);if(-1==i)throw new Error("Cannot find existingFn");this._stack.splice(i,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);-1!=e&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,i=this._stack.length,o=0;n>o;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;no;o++){for(var r=t[o],s=0;i>s&&(r=this._stack[s](r,o,t),void 0!==r);s++);void 0!==r&&e.push(r)}return e},t.Pipeline.prototype.reset=function(){this._stack=[]},t.Pipeline.prototype.toJSON=function(){return this._stack.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Vector=function(){this._magnitude=null,this.list=void 0,this.length=0},t.Vector.Node=function(t,e,n){this.idx=t,this.val=e,this.next=n},t.Vector.prototype.insert=function(e,n){this._magnitude=void 0;var i=this.list;if(!i)return this.list=new t.Vector.Node(e,n,i),this.length++;if(en.idx?n=n.next:(i+=e.val*n.val,e=e.next,n=n.next);return i},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return o;t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o]}return r===t?o:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,i=n-e,o=e+Math.floor(i/2),r=this.elements[o];i>1;)t>r&&(e=o),r>t&&(n=o),i=n-e,o=e+Math.floor(i/2),r=this.elements[o];return r>t?o:t>r?o+1:void 0},t.SortedSet.prototype.intersect=function(e){for(var n=new t.SortedSet,i=0,o=0,r=this.length,s=e.length,a=this.elements,h=e.elements;;){if(i>r-1||o>s-1)break;a[i]!==h[o]?a[i]h[o]&&o++:(n.add(a[i]),i++,o++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,i;return this.length>=t.length?(e=this,n=t):(e=t,n=this),i=e.clone(),i.add.apply(i,n.toArray()),i},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var i={},o=new t.SortedSet,r=e[this._ref],n=void 0===n?!0:n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));i[n.name]=r,t.SortedSet.prototype.add.apply(o,r)},this),this.documentStore.set(r,o),t.SortedSet.prototype.add.apply(this.corpusTokens,o.toArray());for(var s=0;s0&&(i=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=i},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),i=new t.Vector,o=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,h=this,l=this.tokenStore.expand(e).reduce(function(n,o){var r=h.corpusTokens.indexOf(o),s=h.idf(o),l=1,u=new t.SortedSet;if(o!==e){var c=Math.max(3,o.length-e.length);l=1/Math.log(c)}return r>-1&&i.insert(r,a*s*l),Object.keys(h.tokenStore.get(o)).forEach(function(t){u.add(t)}),n.union(u)},new t.SortedSet);o.push(l)},this);var a=o.reduce(function(t,e){return t.intersect(e)});return a.map(function(t){return{ref:t,score:i.similarity(this.documentVector(t))}},this).sort(function(t,e){return e.score-t.score})},t.Index.prototype.documentVector=function(e){for(var n=this.documentStore.get(e),i=n.length,o=new t.Vector,r=0;i>r;r++){var s=n.elements[r],a=this.tokenStore.get(s)[e].tf,h=this.idf(s);o.insert(this.corpusTokens.indexOf(s),a*h)}return o},t.Index.prototype.toJSON=function(){return{version:t.version,fields:this._fields,ref:this._ref,documentStore:this.documentStore.toJSON(),tokenStore:this.tokenStore.toJSON(),corpusTokens:this.corpusTokens.toJSON(),pipeline:this.pipeline.toJSON()}},t.Index.prototype.use=function(t){var e=Array.prototype.slice.call(arguments,1);e.unshift(this),t.apply(this,e)},t.Store=function(){this.store={},this.length=0},t.Store.load=function(e){var n=new this;return n.length=e.length,n.store=Object.keys(e.store).reduce(function(n,i){return n[i]=t.SortedSet.load(e.store[i]),n},{}),n},t.Store.prototype.set=function(t,e){this.has(t)||this.length++,this.store[t]=e},t.Store.prototype.get=function(t){return this.store[t]},t.Store.prototype.has=function(t){return t in this.store},t.Store.prototype.remove=function(t){this.has(t)&&(delete this.store[t],this.length--)},t.Store.prototype.toJSON=function(){return{store:this.store,length:this.length}},t.stemmer=function(){var t={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},e={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},n="[^aeiou]",i="[aeiouy]",o=n+"[^aeiouy]*",r=i+"[aeiou]*",s="^("+o+")?"+r+o,a="^("+o+")?"+r+o+"("+r+")?$",h="^("+o+")?"+r+o+r+o,l="^("+o+")?"+i,u=new RegExp(s),c=new RegExp(h),f=new RegExp(a),d=new RegExp(l),p=/^(.+?)(ss|i)es$/,m=/^(.+?)([^s])s$/,v=/^(.+?)eed$/,y=/^(.+?)(ed|ing)$/,g=/.$/,S=/(at|bl|iz)$/,w=new RegExp("([^aeiouylsz])\\1$"),x=new RegExp("^"+o+i+"[^aeiouwxy]$"),k=/^(.+?[^aeiou])y$/,b=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,E=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,_=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,F=/^(.+?)(s|t)(ion)$/,O=/^(.+?)e$/,P=/ll$/,N=new RegExp("^"+o+i+"[^aeiouwxy]$"),T=function(n){var i,o,r,s,a,h,l;if(n.length<3)return n;if(r=n.substr(0,1),"y"==r&&(n=r.toUpperCase()+n.substr(1)),s=p,a=m,s.test(n)?n=n.replace(s,"$1$2"):a.test(n)&&(n=n.replace(a,"$1$2")),s=v,a=y,s.test(n)){var T=s.exec(n);s=u,s.test(T[1])&&(s=g,n=n.replace(s,""))}else if(a.test(n)){var T=a.exec(n);i=T[1],a=d,a.test(i)&&(n=i,a=S,h=w,l=x,a.test(n)?n+="e":h.test(n)?(s=g,n=n.replace(s,"")):l.test(n)&&(n+="e"))}if(s=k,s.test(n)){var T=s.exec(n);i=T[1],n=i+"i"}if(s=b,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+t[o])}if(s=E,s.test(n)){var T=s.exec(n);i=T[1],o=T[2],s=u,s.test(i)&&(n=i+e[o])}if(s=_,a=F,s.test(n)){var T=s.exec(n);i=T[1],s=c,s.test(i)&&(n=i)}else if(a.test(n)){var T=a.exec(n);i=T[1]+T[2],a=c,a.test(i)&&(n=i)}if(s=O,s.test(n)){var T=s.exec(n);i=T[1],s=c,a=f,h=N,(s.test(i)||a.test(i)&&!h.test(i))&&(n=i)}return s=P,a=c,s.test(n)&&a.test(n)&&(s=g,n=n.replace(s,"")),"y"==r&&(n=r.toLowerCase()+n.substr(1)),n};return T}(),t.Pipeline.registerFunction(t.stemmer,"stemmer"),t.stopWordFilter=function(e){return e&&t.stopWordFilter.stopWords[e]!==e?e:void 0},t.stopWordFilter.stopWords={a:"a",able:"able",about:"about",across:"across",after:"after",all:"all",almost:"almost",also:"also",am:"am",among:"among",an:"an",and:"and",any:"any",are:"are",as:"as",at:"at",be:"be",because:"because",been:"been",but:"but",by:"by",can:"can",cannot:"cannot",could:"could",dear:"dear",did:"did","do":"do",does:"does",either:"either","else":"else",ever:"ever",every:"every","for":"for",from:"from",get:"get",got:"got",had:"had",has:"has",have:"have",he:"he",her:"her",hers:"hers",him:"him",his:"his",how:"how",however:"however",i:"i","if":"if","in":"in",into:"into",is:"is",it:"it",its:"its",just:"just",least:"least",let:"let",like:"like",likely:"likely",may:"may",me:"me",might:"might",most:"most",must:"must",my:"my",neither:"neither",no:"no",nor:"nor",not:"not",of:"of",off:"off",often:"often",on:"on",only:"only",or:"or",other:"other",our:"our",own:"own",rather:"rather",said:"said",say:"say",says:"says",she:"she",should:"should",since:"since",so:"so",some:"some",than:"than",that:"that",the:"the",their:"their",them:"them",then:"then",there:"there",these:"these",they:"they","this":"this",tis:"tis",to:"to",too:"too",twas:"twas",us:"us",wants:"wants",was:"was",we:"we",were:"were",what:"what",when:"when",where:"where",which:"which","while":"while",who:"who",whom:"whom",why:"why",will:"will","with":"with",would:"would",yet:"yet",you:"you",your:"your"},t.Pipeline.registerFunction(t.stopWordFilter,"stopWordFilter"),t.trimmer=function(t){var e=t.replace(/^\W+/,"").replace(/\W+$/,"");return""===e?void 0:e},t.Pipeline.registerFunction(t.trimmer,"trimmer"),t.TokenStore=function(){this.root={docs:{}},this.length=0},t.TokenStore.load=function(t){var e=new this;return e.root=t.root,e.length=t.length,e},t.TokenStore.prototype.add=function(t,e,n){var n=n||this.root,i=t[0],o=t.slice(1);return i in n||(n[i]={docs:{}}),0===o.length?(n[i].docs[e.ref]=e,void(this.length+=1)):this.add(o,e,n[i])},t.TokenStore.prototype.has=function(t){if(!t)return!1;for(var e=this.root,n=0;n element for each result
+ res.results.forEach(function(res) {
+ var $li = $('