diff --git a/config.toml b/config.toml index 8960dde..7383b4f 100644 --- a/config.toml +++ b/config.toml @@ -376,6 +376,12 @@ theme = "doc-theme" identifier = "tutorials@networkprotocols@wifisniffer" parent = "tutorials@networkprotocols" weight = 60 +[[menu.main]] + name = "BLE Mesh" + url = "/tutorials/networkprotocols/blemesh/" + identifier = "tutorials@networkprotocols@blemesh" + parent = "tutorials@networkprotocols" + weight = 70 [[menu.main]] name = "Expansion Boards" @@ -530,6 +536,13 @@ theme = "doc-theme" parent = "firmwareapi@pycom@machine" weight = 100 +[[menu.main]] + name = "Touch" + url = "/firmwareapi/pycom/machine/touch/" + identifier = "firmwareapi@pycom@machine@touch" + parent = "firmwareapi@pycom@machine" + weight = 105 + [[menu.main]] name = "SD" url = "/firmwareapi/pycom/machine/sd/" @@ -627,6 +640,13 @@ theme = "doc-theme" identifier = "firmwareapi@pycom@network@bluetooth@gattscharacteristic" parent = "firmwareapi@pycom@network@bluetooth" weight = 60 +[[menu.main]] + name = "Pymesh BLE" + url = "/firmwareapi/pycom/network/bluetooth/btmesh/" + identifier = "firmwareapi@pycom@network@bluetooth@BLE_Mesh" + parent = "firmwareapi@pycom@network@bluetooth" + weight = 70 + # [Errno 2] No such file or directory: './content/firmwareapi/pycom/network/lora/README.md' [[menu.main]] @@ -736,6 +756,7 @@ theme = "doc-theme" weight = 70 + [[menu.main]] name = "MicroPython Modules" url = "/firmwareapi/micropython/" @@ -1074,6 +1095,18 @@ theme = "doc-theme" identifier = "datasheets@boards@expansion3" parent = "datasheets@boards" weight = 70 +[[menu.main]] + name = "Deepsleep" + url = "/datasheets/expansionboards/deepsleep/" + identifier = "datasheets@boards@deepsleep" + parent = "datasheets@boards" + weight = 80 +[[menu.main]] + name = "PyEthernet" + url = "/datasheets/expansionboards/pyethernet/" + identifier = "datasheets@expansionboards@pyethernet" + parent = "datasheets@boards" + weight = 90 @@ -1324,7 +1357,7 @@ theme = "doc-theme" [[menu.main]] name = "Write configuration" - url = "/pybytes/api/write_config/" + url = "/pybytes/api/update_config/" identifier = "pybytes@api@write_config" parent = "pybytes@api" weight = 38 @@ -1427,12 +1460,19 @@ theme = "doc-theme" parent = "pybytes" weight = 80 - [[menu.main]] - name = "Pymesh Integration" - url = "/pybytes/pymeshintegration/" - identifier = "pybytes@pymeshintegration" - parent = "pybytes" - weight = 90 +[[menu.main]] + name = "Pymesh Integration" + url = "/pybytes/pymeshintegration/" + identifier = "pybytes@pymeshintegration" + parent = "pybytes" + weight = 90 + +[[menu.main]] + name = "Machine Learning" + url = "/pybytes/mlintegration/" + identifier = "pybytes@mlintegration" + parent = "pybytes" + weight = 100 [[menu.main]] name = "Amazon IoT" diff --git a/content/advance/cli.md b/content/advance/cli.md index e804f0b..753fcea 100644 --- a/content/advance/cli.md +++ b/content/advance/cli.md @@ -2,7 +2,7 @@ title: "CLI Updater" aliases: - advance/cli.html - - advance/cli.md + - advance/cli - chapter/advance/cli --- diff --git a/content/datasheets/_index.md b/content/datasheets/_index.md index 3b64541..9e08fb7 100644 --- a/content/datasheets/_index.md +++ b/content/datasheets/_index.md @@ -23,6 +23,7 @@ The follow pages contain all information relating to each product, for example: ## OEM modules - [W01](/datasheets/oem/w01/) +- [G01](/datasheets/oem/g01/) - [L01](/datasheets/oem/l01/) - [L01 OEM Baseboard](/datasheets/oem/l01_reference/) - [L04](/datasheets/oem/l04/) @@ -33,11 +34,10 @@ The follow pages contain all information relating to each product, for example: ## Expansion boards - [Pygate](/datasheets/expansionboards/pygate/) - [Pysense](/datasheets/expansionboards/pysense/) -- [Pysense 2.0 X](/datasheets/expansionboards/pysense/) +- [Pysense 2.0 X](/datasheets/expansionboards/pysense2/) - [Pytrack](/datasheets/expansionboards/pytrack/) -- [Pysense 2.0 X](/datasheets/expansionboards/pysense/) +- [Pytrack 2.0 X](/datasheets/expansionboards/pytrack2/) - [Pyscan](/datasheets/expansionboards/pyscan/) - [Expansion 2](/datasheets/expansionboards/expansion2/) - [Expansion 3](/datasheets/expansionboards/expansion3/) - [Deepsleep](/datasheets/expansionboards/deepsleep/) - diff --git a/content/datasheets/development/fipy.md b/content/datasheets/development/fipy.md index c0063a2..f6973f8 100644 --- a/content/datasheets/development/fipy.md +++ b/content/datasheets/development/fipy.md @@ -26,14 +26,14 @@ The drawing of the LTE-M antenna is available as a [PDF File](/gitbook/assets/lt The Fipy is certified for [CE RED](/gitbook/assets/fipy_c03-b0-red-final.pdf) and [FCC DSS](/gitbook/assets/pycom-2ajmtfipy01r-fcc-grant-dss.pdf) [FCC DTS](/gitbook/assets/pycom-2ajmtfipy01r-fcc-grant-dts.pdf) [FCC DXX](/gitbook/assets/pycom-2ajmtfipy01r-fcc-grant-dxx.pdf) [FCC TNB](/gitbook/assets/pycom-2ajmtfipy01r-fcc-grant-tnb.pdf) [RCM](/gitbook/assets/RCM-Fipy.pdf) -[ROHS certification](gitbook/assets/RoHs_declarations/RoHS-for-FiPy(8217-00091P)-20190523.pdf) +[ROHS certification](/gitbook/assets/RoHs_declarations/RoHS-for-FiPy(8217-00091P)-20190523.pdf) ## Pinout -The pinout of the FiPy is available as a [PDF File](/gitbook/assents/fipy-pinout.pdf) +The pinout of the FiPy is available as a [PDF File](/gitbook/assets/fipy-pinout.pdf) ![](/gitbook/assets/fipy-pinout.png) -> Please note that the PIN assignments for UART1 \(TX1/RX1\), SPI \(CLK, MOSI, MISO\) and I2C \(SDA, SCL\) are defaults and can be changed via software. +> Please note that the PIN assignments for UART1 (TX1/RX1), SPI (CLK, MOSI, MISO) and I2C (SDA, SCL) are defaults and can be changed via software. ## Notes @@ -46,4 +46,4 @@ Always attach the appropriate antenna when using a wireless connection (LoRa / L ### AT Commands -The AT commands for the Sequans Monarch modem on the FiPy are available in a [PDF file](gitbook/assets/Monarch-LR5110-ATCmdRefMan-rev6_noConfidential.pdf). +The AT commands for the Sequans Monarch modem on the FiPy are available in a [PDF file](/gitbook/assets/Monarch-LR5110-ATCmdRefMan-rev6_noConfidential.pdf). diff --git a/content/datasheets/development/gpy.md b/content/datasheets/development/gpy.md index 3eb900a..b0b9f08 100644 --- a/content/datasheets/development/gpy.md +++ b/content/datasheets/development/gpy.md @@ -20,9 +20,9 @@ aliases: The datasheet of the GPy is available as a [PDF File](/gitbook/assets/specsheets/Pycom_002_Specsheets_GPy_v2.pdf) -The drawing of the LTE-M antenna is available as a [PDF File](/gitbook/assets/lte-m-antenna-drawing.pdf") +The drawing of the LTE-M antenna is available as a [PDF File](/gitbook/assets/lte-m-antenna-drawing.pdf) -The Gpy is certified for [CE RED](/gitbook/assets/gpy_c03-b0-red-final.pdf) and [FCC DSS](/gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-dss.pdf) [FCC DTS](/gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-dts.pdf) [FCC TNB](//gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-tnb.pdf) +The Gpy is certified for [CE RED](/gitbook/assets/c03-b0-red-gpy.pdf) and [FCC DSS](/gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-dss.pdf) [FCC DTS](/gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-dts.pdf) [FCC TNB](//gitbook/assets/pycom-2ajmtgpy01r-fcc-grant-tnb.pdf) [RCM](/gitbook/assets/RCM-Gpy.pdf) [ROHS certification](/gitbook/assets/RoHs_declarations/RoHS-for-GPy(8217-00090P)-20190523.pdf) diff --git a/content/datasheets/development/lopy.md b/content/datasheets/development/lopy.md index bb4fc14..f6816fc 100644 --- a/content/datasheets/development/lopy.md +++ b/content/datasheets/development/lopy.md @@ -18,11 +18,10 @@ aliases: ## Datasheet -The datasheet of the LoPy is available as a [PDF File] -(/gitbook/assets/specsheets/Pycom_002_Specsheets_LoPy_v2.pdf) +The datasheet of the LoPy is available as a [PDF File](/gitbook/assets/specsheets/Pycom_002_Specsheets_LoPy_v2.pdf) -The Lopy is certified for [CE RED](/gitbook/assets/16-213298_expertise_pycom_lopy-1.0r.pdf) and [FCC ACC](/gitbook/assets/2090acc16_grant.pdf") [FCC BCC](/gitbook/assets/2090bcc16_grant.pdf) [FCC CCC](/gitbook/assets/2090ccc16_grant.pdf) +The Lopy is certified for [CE RED](/gitbook/assets/16-213298_expertise_pycom_lopy-1.0r.pdf) and [FCC ACC](/gitbook/assets/2090acc16_grant.pdf) [FCC BCC](/gitbook/assets/2090bcc16_grant.pdf) [FCC CCC](/gitbook/assets/2090ccc16_grant.pdf) ## Pinout diff --git a/content/datasheets/development/sipy.md b/content/datasheets/development/sipy.md index 49bb2e3..ce4a8df 100644 --- a/content/datasheets/development/sipy.md +++ b/content/datasheets/development/sipy.md @@ -19,7 +19,7 @@ aliases: The datasheet of the SiPy is available as a [PDF File](/gitbook/assets/specsheets/Pycom_002_Specsheets_SiPy_v2.pdf) -The Sipy is certified for [CE RED](gitbook/assets/17-210585_expertise_sipy_sipy-1.0.pdf) +The Sipy is certified for [CE RED](/gitbook/assets/17-210585_expertise_sipy_sipy-1.0.pdf) ## Pinout diff --git a/content/datasheets/development/wipy2.md b/content/datasheets/development/wipy2.md index c406c33..80d0994 100644 --- a/content/datasheets/development/wipy2.md +++ b/content/datasheets/development/wipy2.md @@ -7,7 +7,7 @@ aliases: - chapter/datasheets/development/wipy2 --- -![](/gitbook/assets/wipy2-1.png) +![](/gitbook/assets/wipy2.png) > Note: Orient the RGB LED / reset button over the USB connector on any expansion board @@ -40,11 +40,11 @@ Always attach the appropriate antenna when using a wireless connection. For WiFi ### Deep Sleep -Due to a couple of issues with the WiPy2 design, the module draws more current than it should while in Deep Sleep. The DC-DC switching regulator always stays in high performance mode, which is used to provide the lowest possible output ripple when the module is in use. In this mode, it draws a quiescent current of 10mA. When the regulator is put into ECO mode the quiescent current drops to 10uA. Unfortunately, the pin used to control this mode is out of the RTC domain. This means that it is not usable during Deep Sleep. This results in the regulator remaining in PWM mode, keeping its quiescent current at 10mA. The flash chip also doesn't enter into power down mode as the CS pin floats during Deep Sleep. This causes the flash chip to consume around 2mA of current. To work around this issue a ["deep sleep shield"](../../boards/deepsleep/) is available that attaches to the module and allows power to be cut off from the device. The device can then be re-enabled either through a timer or via a pin interrupt. With the Deep Sleep Shield, the current consumption during deep sleep is between 7uA and 10uA depending on the wake sources configured. +Due to a couple of issues with the WiPy2 design, the module draws more current than it should while in Deep Sleep. The DC-DC switching regulator always stays in high performance mode, which is used to provide the lowest possible output ripple when the module is in use. In this mode, it draws a quiescent current of 10mA. When the regulator is put into ECO mode the quiescent current drops to 10uA. Unfortunately, the pin used to control this mode is out of the RTC domain. This means that it is not usable during Deep Sleep. This results in the regulator remaining in PWM mode, keeping its quiescent current at 10mA. The flash chip also doesn't enter into power down mode as the CS pin floats during Deep Sleep. This causes the flash chip to consume around 2mA of current. To work around this issue a ["deep sleep shield"]../expansionboards/deepsleep/) is available that attaches to the module and allows power to be cut off from the device. The device can then be re-enabled either through a timer or via a pin interrupt. With the Deep Sleep Shield, the current consumption during deep sleep is between 7uA and 10uA depending on the wake sources configured. ## Tutorials Tutorials on the WiPy2 module can be found in the [examples](/tutorials/introduction) section of this documentation. The following tutorials might be of interest for those using the WiPy2: -* [WiFi connection](/tutorials/all/wlan) -* [BLE](/tutorials/all/ble) +* [WiFi connection](/tutorials/networks/wlan) +* [BLE](/tutorials/networks/ble) diff --git a/content/datasheets/development/wipy3.md b/content/datasheets/development/wipy3.md index 5d99ef4..78f9933 100644 --- a/content/datasheets/development/wipy3.md +++ b/content/datasheets/development/wipy3.md @@ -7,7 +7,7 @@ aliases: - chapter/datasheets/development/wipy3 --- -![](/gitbook/assets/wipy3.png) +![](/gitbook/assets/wipy2.png) > Note: Orient the RGB LED / reset button over the USB connector on any expansion board diff --git a/content/datasheets/expansionboards/_index.md b/content/datasheets/expansionboards/_index.md index aba81af..1ff4034 100644 --- a/content/datasheets/expansionboards/_index.md +++ b/content/datasheets/expansionboards/_index.md @@ -13,4 +13,5 @@ This section contains all of the datasheets for the Pycom Expansion Boards and S * [Pytrack 2.0 X](../expansionboards/pytrack2/) * [Pyscan](../expansionboards/pyscan/) * [Expansion 2](../expansionboards/expansion2/) -* [Expansion 3](../expansionboards/expansion3/) \ No newline at end of file +* [Expansion 3](../expansionboards/expansion3/) +* [Deepsleep](../expansionboards/deepsleep/) \ No newline at end of file diff --git a/content/datasheets/expansionboards/deepsleep.md b/content/datasheets/expansionboards/deepsleep.md index 57c0162..8f15a00 100644 --- a/content/datasheets/expansionboards/deepsleep.md +++ b/content/datasheets/expansionboards/deepsleep.md @@ -2,6 +2,12 @@ title: "Deep Sleep Shield" aliases: --- + +![](/gitbook/assets/deepsleep-image-1.jpg) + +**Store**: Discontinued + + >The Deep Sleep Shield works very similar to how the Pysense / Pytrack sleep modes work The schematic of the Deep Sleep Shield is available as a [PDF File](/gitbook/assets/deepsleep-schematic.pdf) @@ -14,9 +20,8 @@ The pinout of the Deep Sleep Shield is available as a [PDF File](/gitbook/assets ![](/gitbook/assets/deepsleep-pinout.png) -{{% hint style="info" %}} -To correctly connect a WiPy 2.0, LoPy or SiPy to the Deep Sleep Shield, align the white triangle on the Shield with the LED of the Pycom Device. Once the Pycom Device is seated onto the Deep Sleep Shield, this can then be connected to the Expansion Board -{{% /hint %}} -![](/gitbook/assets/deepsleep-image-1.jpg) +> To correctly connect a WiPy 2.0, LoPy or SiPy to the Deep Sleep Shield, align the white triangle on the Shield with the LED of the Pycom Device. Once the Pycom Device is seated onto the Deep Sleep Shield, this can then be connected to the Expansion Board + + diff --git a/content/datasheets/expansionboards/expansion2.md b/content/datasheets/expansionboards/expansion2.md index 20cb589..08e7980 100644 --- a/content/datasheets/expansionboards/expansion2.md +++ b/content/datasheets/expansionboards/expansion2.md @@ -30,6 +30,7 @@ Be gentle when plugging and unplugging from the USB connector. Whilst the USB co {{% /hint %}} ## Notes + ### Battery Charger -The Expansion Board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, the Expansion Board will charge the battery \(if connected\). When the `CHG` jumper is present, the battery will be charged at `450mA`. If this value is too high for your application, removing the jumper lowers the charge current to `100mA`. +The Expansion Board features a single cell Li-Ion/Li-Po charger with a . When the board is being powered via the micro USB connector, the Expansion Board will charge the battery (if connected). When the `CHG` jumper is present, the battery will be charged at `450mA`. If this value is too high for your application, removing the jumper lowers the charge current to `100mA`. diff --git a/content/datasheets/expansionboards/expansion3.md b/content/datasheets/expansionboards/expansion3.md index a083db1..790c6e0 100644 --- a/content/datasheets/expansionboards/expansion3.md +++ b/content/datasheets/expansionboards/expansion3.md @@ -35,7 +35,7 @@ The expansion board contains 6 headers labeled: ### Battery Charger > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. -The Expansion Board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, the Expansion Board will charge the battery \(if connected\). When the `CHG` jumper is present, the battery will be charged at `450mA`. If this value is too high for your application, removing the jumper lowers the charge current to `100mA`. +The Expansion Board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, the Expansion Board will charge the battery (if connected). When the `CHG` jumper is present, the battery will be charged at `450mA`. If this value is too high for your application, removing the jumper lowers the charge current to `100mA`. > To use the battery, pull `P8/G15` high (connect to `3v3`). If you want to use the SD card as well, use a 10k pull-up. @@ -55,8 +55,9 @@ The Expansion Board features a single cell Li-Ion/Li-Po charger. When the board ## Troubleshooting -* If PIC stays in bootloader mode, the [`dfu-util` update](/pytrackpysense/installation/firmware) should be performed +* If PIC stays in bootloader mode, the [`dfu-util` update](/updatefirmware/expansionboard/) should be performed ## 3D model for case design -* Please see the 3D model (step format) +* Please see the [3D model](/gitbook/assets/Expansion_Board_3D.step) (step format) + diff --git a/content/datasheets/expansionboards/pyethernet.md b/content/datasheets/expansionboards/pyethernet.md index 3fabcdc..4720e39 100644 --- a/content/datasheets/expansionboards/pyethernet.md +++ b/content/datasheets/expansionboards/pyethernet.md @@ -6,10 +6,12 @@ title: "PyEthernet" The PyEthernet is a module meant for the [Pygate](../pygate/) expansionboard, enabeling communication and Power over Ethernet. The module will fit on the Pygate in two ways, but only one is correct. Make sure the RJ45 Ethernet port is facing the other way compared to the RGB LED, like shown in the figure below. -![](/gitbook/assets/pyethernet.png) ![](/gitbook/assets/pygate_ethernet.png) +![](/gitbook/assets/pyethernet.png) + +![](/gitbook/assets/pygate_ethernet.png) > Note that the PyEthernet can also work without PoE, you will just need to connect it to a different power source -# Datasheet +## Datasheet We currently have no datasheet available for the module. On the bottom, near the pinheaders, you can find labels for the pin functions. The pins are used to connect both power and a SPI bus. diff --git a/content/datasheets/expansionboards/pygate.md b/content/datasheets/expansionboards/pygate.md index 1b7c7b8..e6504e0 100644 --- a/content/datasheets/expansionboards/pygate.md +++ b/content/datasheets/expansionboards/pygate.md @@ -39,7 +39,7 @@ The case will also work for the regular expansion board and has the SD card hold ## Notes ### Battery Charger -The Pygate features a single cell Li-Ion/Li-Po charger. When the board is being powered via the USB-C connector, the Pygate will charge the battery if connected. +The Pygate features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the USB-C connector, the Pygate will charge the battery if connected. > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. ### Troubleshooting diff --git a/content/datasheets/expansionboards/pyscan.md b/content/datasheets/expansionboards/pyscan.md index d86a98a..3a41140 100644 --- a/content/datasheets/expansionboards/pyscan.md +++ b/content/datasheets/expansionboards/pyscan.md @@ -21,12 +21,6 @@ The datasheet of the Pyscan is available as a [PDF File](/gitbook/assets/pyscan- * Pyscan libraries to use the RFID/NFC reader are located [here](https://github.com/pycom/pycom-libraries/tree/master/pyscan) * The accelerometer library is [here](https://github.com/pycom/pycom-libraries/blob/master/pytrack/lib/LIS2HH12.py) -{{% hint style="info" %}} -For the time being, we recommend uploading the `MFRC630.mpy` file via FTP due to current Pymakr limitations that will be fixed shortly. -{{% /hint %}} - -Libraries for the rest of the components will be added soon. - ## Pyscan components: * **Accelerometer**: ST LIS2HH12 @@ -35,7 +29,7 @@ Libraries for the rest of the components will be added soon. ## Driver -The Windows 7 driver for Pyscan is located [here](/pytrackpysense/installation/firmware). +The Windows 7 driver for Pyscan is located [here](/gettingstarted/software/drivers/). For other Operating Systems, no driver is required. @@ -48,7 +42,7 @@ The pinout of the Pyscan is available as a [PDF File](/gitbook/assets/pyscan-pin ## Battery Charger -The board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, it will charge the battery (if connected). +The board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, it will charge the battery (if connected). diff --git a/content/datasheets/expansionboards/pysense.md b/content/datasheets/expansionboards/pysense.md index 14487f1..0390217 100644 --- a/content/datasheets/expansionboards/pysense.md +++ b/content/datasheets/expansionboards/pysense.md @@ -25,7 +25,7 @@ The pinout of the Pysense is available as a [PDF File](/gitbook/assets/pysense-p ## Notes ### Battery Charger -The board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, it will charge the battery (if connected). +The board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, it will charge the battery (if connected). > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. ### Mechanical Dimensions diff --git a/content/datasheets/expansionboards/pysense2.md b/content/datasheets/expansionboards/pysense2.md index 24689b9..98f84f1 100644 --- a/content/datasheets/expansionboards/pysense2.md +++ b/content/datasheets/expansionboards/pysense2.md @@ -11,10 +11,11 @@ aliases: ## Datasheet -The datasheet of the Pysense 2.0X is available as a [PDF File](gitbook/assets/PySense2X_specsheet.pdf) +The datasheet of the Pysense 2.0X is available as a [PDF File](/gitbook/assets/PySense2X_specsheet.pdf) ## Pinout +The PyPort connector is for a 6 lead mini ribbon cable. Part: Amphenol 20021511-00006T4LF The pinout of the Pysense is available as a [PDF File](/gitbook/assets/pysense2-pinout.pdf) @@ -22,7 +23,7 @@ The pinout of the Pysense is available as a [PDF File](/gitbook/assets/pysense2- ## Notes ### Battery Charger -The board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, it will charge the battery (if connected). +The board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, it will charge the battery (if connected). > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. ### Mechanical Dimensions diff --git a/content/datasheets/expansionboards/pytrack.md b/content/datasheets/expansionboards/pytrack.md index f6fab12..ba90570 100644 --- a/content/datasheets/expansionboards/pytrack.md +++ b/content/datasheets/expansionboards/pytrack.md @@ -26,7 +26,7 @@ The pinout of the Pytrack is available as a [PDF File](/gitbook/assets/pytrack-p ## Notes ### Battery Charger -The board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, it will charge the battery (if connected). +The board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, it will charge the battery (if connected). > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. @@ -36,4 +36,4 @@ The board features a single cell Li-Ion/Li-Po charger. When the board is being p ### 3D model for case design -* Please see the [3D model](/gitbook/assets/PyTrack_v1.1.step") (step format) +* Please see the [3D model](/gitbook/assets/PyTrack_v1.1.step) (step format) diff --git a/content/datasheets/expansionboards/pytrack2.md b/content/datasheets/expansionboards/pytrack2.md index d14c782..1664a1e 100644 --- a/content/datasheets/expansionboards/pytrack2.md +++ b/content/datasheets/expansionboards/pytrack2.md @@ -15,6 +15,7 @@ The datasheet of the Pytrack is available as a [PDF File](/gitbook/assets/PyTrac ## Pinout +The PyPort connector is for a 6 lead mini ribbon cable. Part: Amphenol 20021511-00006T4LF The pinout of the Pytrack is available as a [PDF File]( /gitbook/assets/pytrack2-pinout.pdf) @@ -22,7 +23,7 @@ The pinout of the Pytrack is available as a [PDF File]( ## Notes ### Battery Charger -The board features a single cell Li-Ion/Li-Po charger. When the board is being powered via the micro USB connector, it will charge the battery (if connected). +The board features a single cell Li-Ion/Li-Po charger with a JST PHR‑2 connector. When the board is being powered via the micro USB connector, it will charge the battery (if connected). > Make sure you check the polarity of the battery before plugging it in! Connect the positive side to the side marked with a `+`. diff --git a/content/datasheets/oem/g01.md b/content/datasheets/oem/g01.md index ac848ab..0f42d65 100644 --- a/content/datasheets/oem/g01.md +++ b/content/datasheets/oem/g01.md @@ -7,7 +7,7 @@ aliases: - chapter/datasheets/oem/g01 --- -## ![](/gitbook/assets/g01-1%20%282%29.png) +![](/gitbook/assets/g01-1.png) ## Datasheet @@ -19,7 +19,7 @@ The drawings for the G01 are available as a [PDF File](/gitbook/assets/specsheet The pinout of the G01 is available as a [PDF File](/gitbook/assets/g01-pinout.pdf) -The G01 is certified for [CE RED](/gitbook/assets/17-213357_red-certificate_pycom_g01-1.0.pdf) and [FCC DSS](/gitbook/assets/pycom-2ajmtg01r-fcc-grant-dss.pdf) +The G01 is certified for [CE RED](/gitbook/assets/c03-b0-red-final-g01.pdf) and [FCC DSS](/gitbook/assets/pycom-2ajmtg01r-fcc-grant-dss.pdf) [FCC DTS](/gitbook/assets/pycom-2ajmtg01r-fcc-grant-dts.pdf) [FCC TNB](/gitbook/assets/pycom-2ajmtg01r-fcc-grant-tnb.pdf) [RCM](/gitbook/assets/RCM-G01.pdf) diff --git a/content/datasheets/oem/l01.md b/content/datasheets/oem/l01.md index 2ea349a..0f32590 100644 --- a/content/datasheets/oem/l01.md +++ b/content/datasheets/oem/l01.md @@ -13,7 +13,7 @@ aliases: The drawings for the L01 are available as a [PDF File](/gitbook/assets/specsheets/Pycom_002_Specsheets_L01_v2.pdf) -The L01 is certified for [CE RED](gitbook/assets/17-213356_red-certificate_pycom_l01-1.0.pdf) and [FCC DSS](/gitbook/assets/172181413_aa_00_final.pdf) +The L01 is certified for [CE RED](/gitbook/assets/17-213356_red-certificate_pycom_l01-1.0.pdf) and [FCC DSS](/gitbook/assets/172181413_aa_00_final.pdf) [FCC DTS](/gitbook/assets/172181414_aa_00_final.pdf) [FCC DAA](/gitbook/assets/172181411_aa_00_final.pdf) [RCM](/gitbook/assets/RCM-L01.pdf) [ROHS certification](/gitbook/assets/RoHs_declarations/RoHS-for-L01(f8217-00088P)-20190523.pdf) diff --git a/content/datasheets/oem/universal_reference.md b/content/datasheets/oem/universal_reference.md index 2f31ada..57bb39b 100644 --- a/content/datasheets/oem/universal_reference.md +++ b/content/datasheets/oem/universal_reference.md @@ -40,5 +40,5 @@ The schematic of the OEM baseboard reference is available as a [PDF File](/gitbo ## Altium Project and Gerber Files -The Altium Project and Gerber files are also available as a [ZIP File](gitbook/assets/oem-universal-baseboard-ref.zip) +The Altium Project and Gerber files are also available as a [ZIP File](/gitbook/assets/oem-universal-baseboard-ref.zip) diff --git a/content/firmwareapi/micropython/_index.md b/content/firmwareapi/micropython/_index.md index d13406a..69ba761 100644 --- a/content/firmwareapi/micropython/_index.md +++ b/content/firmwareapi/micropython/_index.md @@ -7,7 +7,5 @@ The following list contains the standard Python libraries, MicroPython-specific 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. -{{% hint style="info" %}} -Some modules are available by an u-name, and also by their non-u-name. The non-u-name can be overridden by a file of that name in your package path. For example, `import json` will first search for a file `json.py` or directory `json` and load that package if it's found. If nothing is found, it will fallback to loading the built-in `ujson` module. -{{% /hint %}} +> Some modules are available by an u-name, and also by their non-u-name. The non-u-name can be overridden by a file of that name in your package path. For example, `import json` will first search for a file `json.py` or directory `json` and load that package if it's found. If nothing is found, it will fallback to loading the built-in `ujson` module. diff --git a/content/firmwareapi/micropython/_thread.md b/content/firmwareapi/micropython/_thread.md index 625adf1..843a819 100644 --- a/content/firmwareapi/micropython/_thread.md +++ b/content/firmwareapi/micropython/_thread.md @@ -28,29 +28,39 @@ for i in range(2): ## Methods -#### \_thread.start\_new\_thread(function, args\[, kwargs\]) +### _thread.start_new_thread(function, args[, kwargs]) Start a new thread and return its identifier. The thread executes the function with the argument list args (which must be a tuple). The optional `kwargs` argument specifies a dictionary of keyword arguments. When the function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run). -#### \_thread.exit() +```python +import _thread + +def foo(arg): + print(arg) + +arg="hello" +_thread.start_new_thread(foo, (arg,)) +``` + +### _thread.exit() Raise the `SystemExit` exception. When not caught, this will cause the thread to exit silently. -#### \_thread.allocate\_lock() +### _thread.allocate_lock() Return a new lock object. Methods of locks are described below. The lock is initially unlocked. -#### \_thread.get\_ident() +### _thread.get_ident() Return the `thread identifier` of the current thread. This is a nonzero integer. Its value has no direct meaning; it is intended as a magic cookie to be used e.g. to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits and another thread is created. -#### \_thread.stack\_size(\[size\]) +### _thread.stack_size([size]) Return the thread stack size (in bytes) used when creating new threads. The optional size argument specifies the stack size to be used for subsequently created threads, and must be `0` (use platform or configured default) or a positive integer value of at least `4096` (4KiB). 4KiB is currently the minimum supported stack size value to guarantee sufficient stack space for the interpreter itself. ## Objects -#### \_thread.LockType +### _thread.LockType This is the type of lock objects. @@ -58,11 +68,11 @@ This is the type of lock objects. Used for synchronisation between threads -### Methods +## Methods Lock objects have the following methods: -#### lock.acquire(waitflag=1, timeout=-1) +### lock.acquire(waitflag=1, timeout=-1) Without any optional argument, this method acquires the lock unconditionally, if necessary waiting until it is released by another thread (only one thread at a time can acquire a lock — that's their reason for existence). @@ -72,11 +82,11 @@ If the floating-point timeout argument is present and positive, it specifies the The return value is `True` if the lock is acquired successfully, `False` if not. -#### lock.release() +### lock.release() Releases the lock. The lock must have been acquired earlier, but not necessarily by the same thread. -#### lock.locked() +### lock.locked() Return the status of the lock: `True` if it has been acquired by some thread, `False` if not. diff --git a/content/firmwareapi/micropython/array.md b/content/firmwareapi/micropython/array.md index 8b64f52..4062afe 100644 --- a/content/firmwareapi/micropython/array.md +++ b/content/firmwareapi/micropython/array.md @@ -8,21 +8,35 @@ aliases: 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). + ## Classes -#### class array.array(typecode\[, iterable\]) +### class array.array(typecode, [iterable]) -Create array with elements of given type. Initial contents of the array are given by an iterable. If it is not provided, an empty array is created. +Create array with elements of given type. Initial contents of the array are given by an iterable. If it is not provided, an empty array is created. Supported format codes: +* `b`: signed char, 1 byte +* `B`: unsigned char, 1 byte +* `h`: signed short, 2 bytes +* `H`: unsigned short, 2 bytes +* `i`: signed int, 2 bytes +* `I`: unsigned int, 2 bytes +* `l`: signed long, 4 bytes +* `L`: unsigned long, 4 bytes +* `q`: signed long long, 8 bytes +* `Q`: unsigned long long, 8 bytes +* `f`: foat, 4 bytes +* `d`: double, 8 bytes + +Adapting the typecode to the array-type you want to create can save a lot of space on the microcontroller ## Methods -#### array.append(val) +### array.append(val) Append new element to the end of array, growing it. -#### array.extend(iterable) +### array.extend(iterable) Append new elements as contained in an iterable to the end of array, growing it. diff --git a/content/firmwareapi/micropython/builtin.md b/content/firmwareapi/micropython/builtin.md index cb167ad..cdf7f13 100644 --- a/content/firmwareapi/micropython/builtin.md +++ b/content/firmwareapi/micropython/builtin.md @@ -8,124 +8,148 @@ aliases: All builtin functions are described here. -abs() +### abs(val) -all() +Returns the absolute value of val -any() +### all(itereable) -bin() +Returns true if all items in an iterable are value `True` -class bool +### any(iterable) -class bytearray +Returns true if any of the items in an iterable are value `True` -class bytes +### bin(val) -callable() +Returns the binary equivalent of the given integer -chr() +### bytearray([source, encoding, errors]) -class method() +Returns the bytearray of the bytes array passed in -compile() +### bytes() -class complex +Similar to `bytearray()` but for a single byte -class dict +### callable(object) -dir() +Returns True if the object appears callable -divmod() +### chr(val) -enumerate() +Returns a character from an integer -eval() +### classmethod(foo) -exec() +Returns a classmethod for the passed function -filter() +### complex([real, imag]) -class float +Creates a complex number from the passed variables. +> You can also use the textual notation `'a+bj'`, e.g. `'1+2j'` -class frozenset +### delattr(object, name) -getattr() +Deletes attribute from the object. -globals() +### dir([object]) -hasattr() +Returns a list of valid attributes of the object. If no parameter is passed, it will return all created objects. -hash() +### divmod(x, y) -hex() +Divides and mods the two values. Similar to `(x / y, x % y)` \ +Returns a tuple `(q, r)` of the two paramters, with quotient `q` and remainder `r` -id() +### numerate() -input() +### eval() -class int +### exec() -isinstance() +### filter() -issubclass() +### class float -iter() +### class frozenset -len() +### getattr() -class list +### globals() -locals() +### hasattr() -map() +### hash() -max() +### hex() -class memoryview +### id() -min() +### input() -next() +### class int -class object +### isinstance() -oct() +### issubclass() -open() +### iter() -ord() +### len() -pow() +### class list -print() +### locals() -property() +### map() -range() +### max() -repr() +### class memoryview -reversed() +### min() -round() +### next() -class set +### class object -setattr() +### oct() -sorted() +### open() -staticmethod() +### ord() -class str +### pow() -sum() +### print() -super() +### property() -class tuple +### range() -type() +### repr() -zip() +### reversed() + +### round() + +### class set + +### setattr() + +### sorted() + +### staticmethod() + +### class str + +### sum() + +### super() + +### class tuple + +### type() + +### zip() diff --git a/content/firmwareapi/micropython/usocket.md b/content/firmwareapi/micropython/usocket.md index a0224fe..7811d49 100644 --- a/content/firmwareapi/micropython/usocket.md +++ b/content/firmwareapi/micropython/usocket.md @@ -129,7 +129,7 @@ The socket must be in blocking mode; it can have a timeout, but the file object' #### 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.md#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#socket-readall), see below. #### socket.readall() diff --git a/content/firmwareapi/micropython/ussl.md b/content/firmwareapi/micropython/ussl.md index 80347f0..c8ed941 100644 --- a/content/firmwareapi/micropython/ussl.md +++ b/content/firmwareapi/micropython/ussl.md @@ -10,7 +10,7 @@ This module provides access to Transport Layer Security (often known as "Secure ## Methods -#### ssl.wrap\_socket(sock, keyfile=None, certfile=None, server\_side=False, cert\_reqs=CERT\_NONE, ssl\_version=0, ca\_certs=None, server\_hostname=None, timeout=10sec) +### ssl.wrap_socket(sock, [keyfile=None, certfile=None, server_side=False, cert_reqs=CERT_NONE, ssl_version=0, ca_certs=None, server_hostname=None, saved_session=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: @@ -40,6 +40,23 @@ SSL sockets inherit all methods and from the standard sockets, see the `usocket` `timeout` : specify a Timeout in Seconds for the SSL handshake operation between client and server, default is 10 seconds +#### ssl.save\_session(ssl_sock) + +Takes an instance `ssl_sock` of `ssl.SSLSocket`, and returns an instance of `ssl.SSLSession`. Saved session can be resumed later, thereby reducing mobile data and time required. Example: + +```python +import socket +import ssl +s = socket.socket() +ss = ssl.wrap_socket(s) +ss.connect(socket.getaddrinfo('www.google.com', 443)[0][-1]) +ses = ssl.save_session(ss) +ss.close() +ss = ssl.wrap_socket(s, saved_session=ses) +ss.connect(socket.getaddrinfo('www.google.com', 443)[0][-1]) +``` + + ## Exceptions * `ssl.SSLError` diff --git a/content/firmwareapi/notes.md b/content/firmwareapi/notes.md index c108d15..00a756d 100644 --- a/content/firmwareapi/notes.md +++ b/content/firmwareapi/notes.md @@ -14,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`](../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. +Currently, there are 2 classes that support interrupts; the [`Alarm`](../pycom/machine/timer#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/aes.md b/content/firmwareapi/pycom/aes.md index 543a18d..b74df82 100644 --- a/content/firmwareapi/pycom/aes.md +++ b/content/firmwareapi/pycom/aes.md @@ -8,9 +8,8 @@ aliases: 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" %}} -AES is implemented using the ESP32 hardware module. -{{% /hint %}} +>AES is implemented using the ESP32 hardware module. + ## Quick Usage Example @@ -32,36 +31,40 @@ print(original) ## Constructors -#### class ucrypto.AES(key, mode, IV, \* , counter, segment\_size) +### class ucrypto.AES(key, [mode=AES.MODE_ECB, IV, counter, segment_size]) Create an AES object that will let you encrypt and decrypt messages. The arguments are: * `key` (byte string) is the secret key to use. It must be 16 (AES-128), 24 (AES-192), or 32 (AES-256) bytes long. -* `mode` is the chaining mode to use for encryption and decryption. Default is `AES.MODE_ECB`. +* `mode` is the chaining mode to use for encryption and decryption. Can be the following values: + * `AES.MODE_ECB`: Electronic Code Book. Simplest encryption mode. + * `AES.MODE_CBC`: Cipher-Block Chaining. An Initialisation Vector (IV) is required. + * `AES.MODE_CFB`: Cipher feedback. `plaintext` and `ciphertext` are processed in segments of `segment_size` bits. Works as a stream cipher. + * `AES.MODE_CTR`: Counter mode. Each message block is associated to a counter which must be unique across all messages that get encrypted with the same key. * `IV` (byte string) initialisation vector. Should be 16 bytes long. It is ignored in modes `AES.MODE_ECB` and `AES.MODE_CRT`. +> To avoid security issues, IV should always be a random number and should never be reused to encrypt two different messages. The same applies to the counter in CTR mode. You can use `crypto.getrandbits()` for this purpose. * `counter` (byte string) used only for `AES.MODE_CTR`. Should be 16 bytes long. Should not be reused. -* `segment_size` is the number of bits `plaintext` and `ciphertext` are segmented in. Is only used in `AES.MODE_CFB`. Supported values are `AES.SEGMENT_8` and `AES.SEGMENT_128` +* `segment_size` is the number of bits `plaintext` and `ciphertext` are segmented in. Is only used in `AES.MODE_CFB`. Supported values are: + * `AES.SEGMENT_8` + * `AES.SEGMENT_128` + + ## Methods -#### ucrypto.encrypt() +### ucrypto.encrypt() Encrypt data with the key and the parameters set at initialisation. -#### ucrypto.decrypt() +### ucrypto.decrypt() Decrypt data with the key and the parameters set at initialisation. ## Constants -* `AES.MODE_ECB`: Electronic Code Book. Simplest encryption mode. It does not hide data patterns well (see this article for more info) -* `AES.MODE_CBC`: Cipher-Block Chaining. An Initialisation Vector (IV) is required. -* `AES.MODE_CFB`: Cipher feedback. `plaintext` and `ciphertext` are processed in segments of `segment_size` bits. Works a stream cipher. -* `AES.MODE_CTR`: Counter mode. Each message block is associated to a counter which must be unique across all messages that get encrypted with the same key. -* `AES.SEGMENT_8`, `AES.SEGMENT_128`: Length of the segment for `AES.MODE_CFB` +* `AES.MODE_ECB`, `AES.MODE_CBC`, `AES.MODE_CFB`, `AES.MODE_CTR` +* `AES.SEGMENT_8`, `AES.SEGMENT_128` + -{{% hint style="danger" %}} -To avoid security issues, IV should always be a random number and should never be reused to encrypt two different messages. The same applies to the counter in CTR mode. You can use `crypto.getrandbits()` for this purpose. -{{% /hint %}} diff --git a/content/firmwareapi/pycom/expansionboards/_index.md b/content/firmwareapi/pycom/expansionboards/_index.md index d3662c8..8829d29 100644 --- a/content/firmwareapi/pycom/expansionboards/_index.md +++ b/content/firmwareapi/pycom/expansionboards/_index.md @@ -19,7 +19,7 @@ These libraries should be uploaded to a device (LoPy, SiPy, WiPy 3.0, etc.) in t Add as many or as few of the libraries that are required. -In addition to the Pysense or Pytrack specific libraries, for hardware version 1.x boards you also need to upload the `pycoproc.py` file from the `_lib/pycoproc_` folder inside the libraries archive. For the Pytrack 2.0 X and Pysense 2.0 X, the pycoproc.py file is included in the pytrack-2 and pysense-2 directories to avoid confusion over which library to use. +In addition to the Pysense or Pytrack specific libraries, for hardware version 1.x boards you also need to upload the `pycoproc.py` file from the `lib/pycoproc` folder inside the libraries archive. For the Pytrack 2.0 X and Pysense 2.0 X, the pycoproc.py file is included in the pytrack-2 and pysense-2 directories to avoid confusion over which library to use. For example, if using the Pysense and the user wishes to enable the only Accelerometer and the Light Sensor, they should place the following `.py` files into the device's `/lib` folder: diff --git a/content/firmwareapi/pycom/machine/_index.md b/content/firmwareapi/pycom/machine/_index.md index 8b17eaf..dcefca9 100644 --- a/content/firmwareapi/pycom/machine/_index.md +++ b/content/firmwareapi/pycom/machine/_index.md @@ -4,7 +4,6 @@ aliases: --- The `machine` module contains specific functions related to the board. - ### Quick Usage Example ```python @@ -18,92 +17,111 @@ machine.unique_id() # return the 6-byte unique id of the board (the LoPy's WiFi ## Reset Functions -#### machine.reset() +### machine.reset() Resets the device in a manner similar to pushing the external RESET button. -#### machine.reset\_cause() +### machine.reset_cause() -Get the reset cause. See constants for the possible return values. +Returns an integer. The possible values are: +* `machine.PWRON_RESET`: Reset by power on or reset button +* `machine.HARD_RESET`: +* `machine.WDT_RESET`: Reset by watchdog timer +* `machine.DEEPSLEEP_RESET`: Reset caused by deepsleep +* `machine.SOFT_RESET`: Reset by e.g. `sys.init()` +* `machine.BROWN_OUT_RESET`: Reset caused by low voltage ## Interrupt Functions -#### machine.disable\_irq() +### machine.disable_irq() Disable interrupt requests. Returns and integer representing the previous IRQ state. This return value can be passed to `enable_irq` to restore the IRQ to its original state. -#### machine.enable\_irq(\[state\]) +### machine.enable_irq(state) Enable interrupt requests. The most common use of this function is to pass the value returned by `disable_irq` to exit a critical section. Another options is to enable all interrupts which can be achieved by calling the function with no parameters. ## Power Functions -#### machine.freq() +### machine.freq() Returns CPU frequency in hertz. -#### machine.idle() +### machine.idle() 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) +### machine.sleep([time_ms, resume_wifi_ble=False]) 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. +* `time_ms` is the sleep time in milliseconds. If not given, it will sleep indefinitely unless power is removed, the reset button is pressed or 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 + * `True` Restore WiFi / BLE connections + * `False` Do not restore WiFi / BLE connections restoration (default) -_Note: in light sleep mode LoRa/Lte modems are stopped and have to be re-initialized after wakeup._ +> Note: in light sleep mode LoRa/LTE modems are stopped and have to be re-initialized after wakeup. -#### machine.deepsleep(\[time\_ms\]) +### 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. +Stops the CPU and all peripherals, including the networking interfaces (except for LTE). Execution is resumed similar to pressing the reset button. The pin states are not held by default. You can choose to hold specific pins using [machine.pin.hold()](../machine/pin/#pinholdhold) + +* `time_ms` is the sleep time in milliseconds. If not given, it will sleep indefinitely unless power is removed, the reset button is pressed or another wakeup source is configured. Products with LTE connectivity, such as the FiPy, GPy, G01, need to have the LTE radio disabled separately via the LTE class before entering deepsleep. This is necessary because the LTE radio is powered independently, which allows for use cases that wake the system from deepsleep by an event from the LTE network, for example receiving data or an SMS. -#### machine.pin\_sleep\_wakeup(pins, mode, enable\_pull) +> Note: in deep sleep mode LoRa/LTE modems are stopped and have to be re-initialized after wakeup. + +### machine.pin_sleep_wakeup(pins, mode, enable_pull) Configure pins to wake up from sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`. The arguments are: * `pins` a list or tuple containing the `GPIO` to setup for sleep wakeup. -* `mode` selects the way the configure `GPIO`s can wake up the module. The possible values are: `machine.WAKEUP_ALL_LOW` and `machine.WAKEUP_ANY_HIGH`. +* `mode` selects the way the configure `GPIO`s can wake up the module. The possible values are: + * `machine.WAKEUP_ALL_LOW` + * `machine.WAKEUP_ANY_HIGH`. * `enable_pull` if set to `True` keeps the pull up or pull down resistors enabled during sleep. If this variable is set to `True`, then `ULP` or capacitive touch wakeup cannot be used in combination with `GPIO` wakeup. -#### machine.wake\_reason() +### machine.wake_reason() -Get the wake reason. See constants for the possible return values. Returns a tuple of the form: `(wake_reason, gpio_list)`. When the wakeup reason is either GPIO or touch pad, then the second element of the tuple is a list with GPIOs that generated the wakeup. +Get the wake reason. See constants for the possible return values. Returns a tuple of the form: `(wake_reason, gpio_list)`. When the wakeup reason is either GPIO or touch pad, then the second element of the tuple is a list with GPIOs that generated the wakeup. The possible wake reasons are: +* `machine.PWRON_WAKE`: Wake up by power on or reset button +* `machine.PIN_WAKE`: Wake up by interrupt on pin +* `machine.RTC_WAKE`: Wake up because sleep time is over +* `machine.ULP_WAKE`: Wake up by touch button -#### machine.remaining\_sleep\_time() -Returns the remaining timer duration (in milliseconds) if the ESP32 is woken up from deep sleep by something other than the timer. For example, if you set the timer for 30 seconds (30000 ms) and it wakes up after 10 seconds then this function will return `20000`. +### machine.remaining_sleep_time() + +Returns the remaining timer duration (in milliseconds) if the ESP32 is woken up from deep sleep by something other than the timer. For example, if you set the timer for 30 seconds (30000 ms) and it wakes up after 10 seconds then this function will return 20000. ## Miscellaneous Functions -#### machine.main(filename) +### machine.main(filename) Set the `filename` of the main script to run after `boot.py` is finished. If this function is not called then the default file `main.py` will be executed. It only makes sense to call this function from within `boot.py`. -#### machine.rng() +### machine.rng() Return a 24-bit software generated random number. -#### machine.unique\_id() +### machine.unique_id() Returns a byte string with a unique identifier of a board/SoC. It will vary from a board/SoC instance to another, if underlying hardware allows. Length varies by hardware (so use substring of a full value if you expect a short ID). In some MicroPython ports, ID corresponds to the network MAC address. -{{% hint style="info" %}} -Use `ubinascii.hexlify()` to convert the byte string to hexadecimal form for ease of manipulation and use elsewhere. -{{% /hint %}} +> Use `ubinascii.hexlify()` to convert the byte string to hexadecimal form for ease of manipulation and use elsewhere. -#### machine.info() +### machine.info() -Returns the high water mark of the stack associated with various system tasks, in words (1 word = 4 bytes on the ESP32). If the value is zero then the task has likely overflowed its stack. If the value is close to zero then the task has come close to overflowing its stack. +Returns the high water mark of the stack associated with various system tasks, in words (1 word = 4 bytes on the ESP32). If the value is zero then the task has likely overflowed its stack. + +### machine.temperature() + +Returns the temperature of the ESP32 core in degrees Farenheit. You can convert this to Celcius by `((machine.temperature() - 32) / 1.8)` ## Constants diff --git a/content/firmwareapi/pycom/machine/adc.md b/content/firmwareapi/pycom/machine/adc.md index 54ca1d4..fa9c5ce 100644 --- a/content/firmwareapi/pycom/machine/adc.md +++ b/content/firmwareapi/pycom/machine/adc.md @@ -8,10 +8,19 @@ aliases: ## class ADC – Analog to Digital Conversion + +{{% development version="" style="block" %}} +{{% /development %}} + + + ### Quick Usage Example +{{% development version="" style="block" %}} + +{{% /development %}} + ```python - import machine adc = machine.ADC() # create an ADC object @@ -19,81 +28,77 @@ apin = adc.channel(pin='P16') # create an analog pin on P16 val = apin() # read an analog value ``` -### Constructors +## Constructors -#### class machine.ADC(id=0) +### class machine.ADC([id=0] {{% development version="" style="inline" %}}hello {{% /development %}}) Create an ADC object; associate a channel with a pin. For more info check the hardware section. -### Methods +## Methods -#### adc.init( \* , bits=12) +### adc.init([bits=12]) Enable the ADC block. This method is automatically called on object creation. -* `Bits` can take values between 9 and 12 and selects the number of bits of resolution of the ADC block. +* `bits` can take values between 9 and 12 and selects the number of bits of resolution of the ADC block. -#### adc.deinit() +### adc.deinit() Disable the ADC block. -#### adc.channel(\* , pin, attn=ADC.ATTN\_0DB) +### adc.channel(pin, attn=ADC.ATTN_0DB) Create an analog pin. * `pin` is a keyword-only string argument. Valid pins are `P13` to `P20`. * `attn` is the attenuation level. The supported values are: `ADC.ATTN_0DB`, `ADC.ATTN_2_5DB`, `ADC.ATTN_6DB`, `ADC.ATTN_11DB` -Returns an instance of `ADCChannel`. Example: +Returns an instance of `ADCChannel`. -```python - -# enable an ADC channel on P16 -apin = adc.channel(pin='P16') -``` - -#### adc.vref(vref) +### adc.vref(vref) If called without any arguments, this function returns the current calibrated voltage (in millivolts) of the `1.1v` reference. Otherwise it will update the calibrated value (in millivolts) of the internal `1.1v` reference. -#### adc.vref\_to\_pin(pin) +### adc.vref_to_pin(pin) Connects the internal `1.1v` to external `GPIO`. It can only be connected to `P22`, `P21` or `P6`. It is recommended to only use `P6` on the WiPy, on other modules this pin is connected to the radio. -### Constants +## Constants -* ADC channel attenuation values: `ADC.ATTN_0DB`, `ADC.ATTN_2_5DB`, `ADC.ATTN_6DB`, `ADC.ATTN_11DB` +* ADC channel attenuation values: (value references are approximations) + * `ADC.ATTN_0DB`: 0dB attenuation. 1V will be registered as 1V + * `ADC.ATTN_2_5DB`: 2.5dB attenuation. 1V will be registered as 0.75V + * `ADC.ATTN_6DB`: 6dB attenuation. 1V will be registered as 0.5V + * `ADC.ATTN_11DB`: 11dB attenuation. 1V will be registered as 0.3V -## class ADCChannel +>Note: The voltages will automatically be corrected by `adcchannel.voltage()` -Read analog values from internal/external sources. ADC channels can be connected to internal points of the `MCU` or to `GPIO` pins. ADC channels are created using the `ADC.channel` method. +## Class ADCChannel - created upon initialisation of an ADC Channel +The following methods can be applied on the `adcchannel()` instance. ADC channels are created using the `ADC.channel(...)` method. -### Methods -#### adcchannel() +### adcchannel() Fast method to read the channel value. -#### adcchannel.value() +### adcchannel.value() Read the channel value. -#### adcchannel.init() +### adcchannel.init() (Re)init and enable the ADC channel. This method is automatically called on object creation. -#### adcchannel.deinit() +### adcchannel.deinit() Disable the ADC channel. -#### adcchannel.voltage() +### adcchannel.voltage() Reads the channels value and converts it into a voltage (in millivolts) -#### adcchannel.value\_to\_voltage(value) +### adcchannel.value_to_voltage(value) Converts the provided value into a voltage (in millivolts) in the same way voltage does. -{{% hint style="danger" %}} -ADC pin input range is `0-1.1V`. This maximum value can be increased up to `3.3V` using the highest attenuation of `11dB`. **Do not exceed the maximum of 3.3V**, to avoid damaging the device. -{{% /hint %}} +> ADC pin input range is `0-1.1V`. This maximum value can be increased up to `3.3V` using the highest attenuation of `11dB`. **Do not exceed the maximum of 3.3V**, to avoid damaging the device. diff --git a/content/firmwareapi/pycom/machine/can.md b/content/firmwareapi/pycom/machine/can.md index 4c825a8..db1e6d7 100644 --- a/content/firmwareapi/pycom/machine/can.md +++ b/content/firmwareapi/pycom/machine/can.md @@ -23,33 +23,35 @@ can.recv() ## Constructors -#### class machine.CAN(bus=0, ...) +### class machine.CAN([bus=0]) 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 ``` ## Methods -#### can.init(mode=CAN.NORMAL, baudrate=500000, \*, frame\_format=CAN.FORMAT\_STD, rx\_queue\_len=128, pins=('P22', 'P23')) +### can.init([mode=CAN.NORMAL, baudrate=500000, frame_format=CAN.FORMAT_STD, rx_queue_len=128, pins=('P22', 'P23')]) Initialize the CAN controller. The arguments are: * `mode` can take either CAN.NORMAL or CAN.SILENT. Silent mode is useful for sniffing the bus. * `baudrate` sets up the bus speed. Acceptable values are between 1 and 1000000. -* `frame_format` defines the frame format to be accepted by the receiver. Useful for filtering frames based on the identifier length. Can tale either `CAN.FORMAT_STD`, `CAN.FORMAT_EXT`, `CAN.FORMAT_BOTH`. If `CAN.FORMAT_STD` is selected, extended frames won't be received and vice-versa. -* `rx_queue_len` defines the number of messages than can be queued by the receiver. Due to CAN being a high traffic bus, large values are recommended (>= 128), otherwise messages will be dropped specially when no filtering is applied. +* `frame_format` defines the frame format to be accepted by the receiver. Useful for filtering frames based on the identifier length. Can tale either: + * `CAN.FORMAT_STD`: With this option, extended frames won't be received and vice-versa. + * `CAN.FORMAT_EXT` + * `CAN.FORMAT_BOTH` +* `rx_queue_len` defines the number of messages than can be queued by the receiver. Due to CAN being a high traffic bus, large values are recommended (>= 128), otherwise messages will be dropped specially when no filtering is applied. * `pins` selects the `Tx` and `Rx` pins (in that order). -#### can.deinit() +### can.deinit() Disables the CAN bus. -#### can.send(id, \* , data=None, rtr=False, extended=False) +### can.send(id, [data=None, rtr=False, extended=False]) Send a CAN frame on the bus @@ -61,7 +63,6 @@ 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 @@ -69,19 +70,18 @@ can.send(id=0x010, data=bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08])) can.send(id=0x012, rtr=True) # sends a remote request for message id=0x12 ``` -#### can.recv(timeout=0) +### can.recv([timeout=0]) Get a message from the receive queue, and optionally specify a timeout value in **s** (can be a floating point value e.g. `0.2`). This function returns `None` if no messages available. If a message is present, it will be returned as a named tuple with the following form: `(id, data, rtr, extended)` ```python - >>> can.recv() (id=0x012, data=b'123', rtr=False, extended=False) ``` -#### can.soft\_filter(mode, filter\_list) +### can.soft_filter(mode, filter_list) Specify a software filter accepting only the messages that pass the filter test. @@ -96,7 +96,6 @@ 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. @@ -106,7 +105,7 @@ can.soft_filter(CAN.FILTER_MASK, [(0x100, 0x7FF), (0x200, 0x7FC)]) # more of the can.soft_filter(None) # disable soft filters, all messages are accepted ``` -#### can.callback(trigger, handler=None, arg=None) +### can.callback(trigger, [handler=None, arg=None]) Set a callback to be triggered when any of this 3 events are present: @@ -123,7 +122,6 @@ 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')) @@ -134,7 +132,7 @@ def can_cb(can_o): can.callback(handler=can_cb, trigger=CAN.RX_FRAME) ``` -#### can.events() +### can.events() This method returns a value with bits sets (if any) indicating the events that have occurred in the bus. 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. diff --git a/content/firmwareapi/pycom/machine/dac.md b/content/firmwareapi/pycom/machine/dac.md index 10058f7..41be0cb 100644 --- a/content/firmwareapi/pycom/machine/dac.md +++ b/content/firmwareapi/pycom/machine/dac.md @@ -23,30 +23,31 @@ dac_tone.tone(1000, 0) # set tone output to 1kHz ## Constructors -#### class class machine.DAC(pin) +### class class machine.DAC(pin) Create a DAC object, that will let you associate a channel with a `pin`. `pin` can be a string argument. ## Methods -#### dac.init() +### dac.init() Enable the DAC block. This method is automatically called on object creation. -#### dac.deinit() +### dac.deinit() Disable the DAC block. -#### dac.write(value) +### dac.write(value) Set the DC level for a DAC pin. `value` is a float argument, with values between 0 and 1. -#### dac.tone(frequency, amplitude) +### dac.tone(frequency, amplitude) Sets up tone signal to the specified `frequency` at `amplitude` scale. `frequency` can be from `125Hz` to `20kHz` in steps of `122Hz`. `amplitude` is an integer specifying the tone amplitude to write the DAC pin. Amplitude value represents: * `0` is 0dBV (~ 3Vpp at 600 Ohm load) -* `1` is -6dBV (~1.5 Vpp), `2` is -12dBV (~0.8 Vpp) +* `1` is -6dBV (~1.5 Vpp), +* `2` is -12dBV (~0.8 Vpp) * `3` is -18dBV (~0.4 Vpp). The generated signal is a sine wave with an DC offset of VDD/2. diff --git a/content/firmwareapi/pycom/machine/i2c.md b/content/firmwareapi/pycom/machine/i2c.md index d75dd1d..0354386 100644 --- a/content/firmwareapi/pycom/machine/i2c.md +++ b/content/firmwareapi/pycom/machine/i2c.md @@ -73,61 +73,60 @@ i2c.writeto_mem(0x42, 0x10, 'xy') # write 2 bytes to slave 0x42, slave memory 0x ## Constructors -#### class machine.I2C(bus, ...) +### class machine.I2C([bus=0], ...) Construct an I2C object on the given `bus`. `bus` can only be `0, 1, 2`. If the `bus` is not given, the default one will be selected (`0`). Buses `0` and `1` use the ESP32 I2C hardware peripheral while bus `2` is implemented with a bit-banged software driver. -## Methods +## General Methods -### General Methods -#### i2c.init(mode, \* , baudrate=100000, pins=(SDA, SCL)) +### i2c.init([mode=I2C.MASTER, baudrate=100000, pins=(SDA='P9', SCL='P10)]) Initialise the I2C bus with the given parameters: * `mode` must be I2C.MASTER * `baudrate` is the SCL clock rate -* pins is an optional tuple with the pins to assign to the I2C bus. The default I2C pins are `P9` (SDA) and `P10` (SCL) +* `pins` is an optional tuple with the pins to assign to the I2C bus. The default I2C pins are `P9` (SDA) and `P10` (SCL) -#### i2c.scan() +### i2c.scan() Scan all I2C addresses between `0x08` and `0x77` inclusive and return a list of those that respond. A device responds if it pulls the SDA line low after its address (including a read bit) is sent on the bus. -### Standard Bus Operations +## Standard Bus Operations The following methods implement the standard I2C master read and write operations that target a given slave device. -#### i2c.readfrom(addr, nbytes) +### i2c.readfrom(addr, nbytes) Read `nbytes` from the slave specified by `addr`. Returns a bytes object with the data read. -#### i2c.readfrom\_into(addr, buf) +### i2c.readfrom_into(addr, buf) Read into `buf` from the slave specified by `addr`. The number of bytes read will be the length of `buf`. Return value is the number of bytes read. -#### i2c.writeto(addr, buf, \* , stop=True) +### i2c.writeto(addr, buf, * , [stop=True]) Write the bytes from `buf` to the slave specified by `addr`. The argument `buf` can also be an integer which will be treated as a single byte. If `stop` is set to `False` then the stop condition won't be sent and the I2C operation may be continued (typically with a read transaction). Return value is the number of bytes written. -### Memory Operations +## Memory Operations Some I2C devices act as a memory device (or set of registers) that can be read from and written to. In this case there are two addresses associated with an I2C transaction: the slave address and the memory address. The following methods are convenience functions to communicate with such devices. -#### i2c.readfrom\_mem(addr, memaddr, nbytes, \*, addrsize=8) +### i2c.readfrom_mem(addr, memaddr, nbytes, [addrsize=8]) Read `nbytes` from the slave specified by `addr` starting from the memory address specified by `memaddr`. The `addrsize` argument is specified in bits and it can only take 8 or 16. -#### i2c.readfrom\_mem\_into(addr, memaddr, buf, \*, addrsize=8) +### i2c.readfrom_mem_into(addr, memaddr, buf, *, [addrsize=8]) Read into `buf` from the slave specified by `addr` starting from the memory address specified by `memaddr`. The number of bytes read is the length of `buf`. The `addrsize` argument is specified in bits and it can only take 8 or 16. The return value is the number of bytes read. -#### i2c.writeto\_mem(addr, memaddr, buf \*, addrsize=8) +### i2c.writeto_mem(addr, memaddr, buf, [addrsize=8]) Write `buf` to the slave specified by `addr` starting from the memory address specified by `memaddr`. The argument `buf` can also be an integer which will be treated as a single byte. The `addrsize` argument is specified in bits and it can only take 8 or 16. diff --git a/content/firmwareapi/pycom/machine/pin.md b/content/firmwareapi/pycom/machine/pin.md index 9202859..5d71b8a 100644 --- a/content/firmwareapi/pycom/machine/pin.md +++ b/content/firmwareapi/pycom/machine/pin.md @@ -28,7 +28,7 @@ p_in() # get value, 0 or 1 ## Constructors -#### class machine.Pin(id, ...) +### class machine.Pin(id, [mode=Pin.OUT, pull=None, alt]) 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) @@ -40,7 +40,7 @@ p = Pin('P10', mode=Pin.OUT, pull=None, alt=-1) ## Methods -#### pin.init(mode, pull, \* , alt) +### pin.init(mode, pull, * , alt) Initialise the pin: @@ -58,18 +58,19 @@ Initialise the pin: Returns: `None`. -#### pin.id() +### pin.id() Get the pin id. -#### pin.value(\[value\]) +### pin.value([value]) -Get or set the digital logic level of the pin: +Get or set the digital logic level of the pin. This only works in `Pin.OUT` mode. Values can be: +* `True` or 1: High +* `False`or 0: Low -* With no argument, return 0 or 1 depending on the logic level of the pin. -* With value given, set the logic level of the pin. value can be anything that converts to a boolean. If it converts to True, the pin is set high, otherwise it is set low. -#### pin(\[value\]) + +### pin([value]) Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin. @@ -84,25 +85,31 @@ pin() # fast method to get the value See `pin.value()` for more details. -#### pin.toggle() +### pin.toggle() Toggle the value of the pin. -#### pin.mode(\[mode\]) +### pin.mode([mode]) -Get or set the pin mode. +Get or set the pin mode. Modes can be: +* `Pin.IN` +* `Pin.OUT` +* `Pin.OPEN_DRAIN` -#### pin.pull(\[pull\]) +### pin.pull([pull]) -Get or set the pin pull. +Get or set the pin pull. Pull can be: +* `Pin.PULL_UP` +* `Pin.PULL_DOWN` +* `None` -#### pin.hold(\[hold\]) +### pin.hold([hold]) Get or set the pin hold. You can apply a hold to a pin by passing `True` (or clear it by passing `False`). When a pin is held, its value cannot be changed by using `Pin.value()` or `Pin.toggle()` until the hold is released. This Can be used to retain the pin state through a core reset and system reset triggered by watchdog time-out or Deep-sleep events. Only pins in the RTC power domain can retain their value through deep sleep or reset. These are: `P2, P3, P4, P6, P8, P9, P10, P13, P14, P15, P16, P17, P18, P19, P20, P21, P22, P23` -#### pin.callback(trigger, handler=None, arg=None) +### pin.callback(trigger, [handler=None, arg=None]) Set a callback to be triggered when the input level at the pin changes. @@ -130,13 +137,12 @@ p_in = Pin('P10', mode=Pin.IN, pull=Pin.PULL_UP) 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](/firmwareapi/notes#interrupt-handling). -{{% /hint %}} +>For more information on how Pycom's products handle interrupts, see [here](/firmwareapi/notes#interrupt-handling). + ## Attributes -#### class pin.exp\_board +### class pin.exp_board Contains all Pin objects supported by the expansion board. Examples: @@ -147,7 +153,7 @@ led = Pin(Pin.exp_board.G16, mode=Pin.OUT) Pin.exp_board.G16.id() ``` -#### class pin.module +### class pin.module Contains all `Pin` objects supported by the module. Examples: diff --git a/content/firmwareapi/pycom/machine/pwm.md b/content/firmwareapi/pycom/machine/pwm.md index fb3148e..a6c13b9 100644 --- a/content/firmwareapi/pycom/machine/pwm.md +++ b/content/firmwareapi/pycom/machine/pwm.md @@ -6,9 +6,7 @@ aliases: - chapter/firmwareapi/pycom/machine/pwm --- -## class PWM – Pulse Width Modulation - -### Quick Usage Example +## Quick Usage Example ```python @@ -19,23 +17,20 @@ pwm_c = pwm.channel(0, pin='P12', duty_cycle=0.5) pwm_c.duty_cycle(0.3) # change the duty cycle to 30% ``` -### Constructors +## Constructors -#### class machine.PWM(timer, frequency) +### class machine.PWM(timer, frequency) -Create a PWM object. This sets up the `timer` to oscillate at the specified `frequency`. `timer` is an integer from 0 to 3. `frequency` is an integer from 1 Hz to 78 KHz (this values can change in future upgrades). +Create a PWM object. This sets up the `timer` to oscillate at the specified `frequency`. `timer` is an integer from 0 to 3. `frequency` is an integer from 1 Hz to 78 KHz. -### Methods +## Methods -#### pwm.channel(id, pin \* , duty\_cycle=0.5) +### pwm.channel(id, pin, [duty_cycle=0.5]) Connect a PWM channel to a pin, setting the initial duty cycle. `id` is an integer from 0 to 7. `pin` is a string argument. `duty_cycle` is a keyword-only float argument, with values between 0 and 1. Returns an instance of `PWMChannel`. -## class PWMChannel — PWM channel -### Methods - -#### pwmchannel.duty\_cycle(value) +### pwmchannel.duty_cycle(value) Set the duty cycle for a PWM channel. `value` is a float argument, with values between 0 and 1. diff --git a/content/firmwareapi/pycom/machine/pygate.md b/content/firmwareapi/pycom/machine/pygate.md index c961b11..7d0c8e1 100644 --- a/content/firmwareapi/pycom/machine/pygate.md +++ b/content/firmwareapi/pycom/machine/pygate.md @@ -6,21 +6,25 @@ aliases: - chapter/firmwareapi/pycom/machine/pygate --- -The Pygate is an 8-channel LoRaWAN gateway. Connect a WiPy, Gpy or LoPy4 board to the Pygate and flash the Pygate firmware. See the [Pygate tutorial](/tutorials/all/pygate) to get started. +The Pygate is an 8-channel LoRaWAN gateway. Connect a WiPy, Gpy or LoPy4 board to the Pygate and flash the Pygate firmware. See the [Pygate tutorial](/tutorials/expansionboards/pygate) to get started. ## Methods -#### machine.pygate\_init(buff) +### machine.pygate_init(config) This function is used to initialize the Pygate -- `buff`: the data contents of the gateway global config json file +- `config`: the data contents of the gateway global config json file -#### machine.pygate\_deinit() +### machine.pygate_deinit() This shuts down the concentrator. -#### machine.callback(trigger, handler=None, arg=None) +### machine.pygate_reset() + +Resets the Pygate and inserted development module (including the LTE modem, if present). This actually power cycles the Pygate and the attached hardware and is **not** similar to `machine.reset()`. + +### machine.callback(trigger, [handler=None, arg=None]) - `trigger`: A trigger event(s) for invoking the callback function `handler`, the triggers/events are: @@ -34,6 +38,6 @@ This shuts down the concentrator. - `arg`: Optional argument to be passed to the callback function. -#### machine.events() +### machine.events() Get the Pygate events \ No newline at end of file diff --git a/content/firmwareapi/pycom/machine/rmt.md b/content/firmwareapi/pycom/machine/rmt.md index fb74379..162a06e 100644 --- a/content/firmwareapi/pycom/machine/rmt.md +++ b/content/firmwareapi/pycom/machine/rmt.md @@ -39,7 +39,7 @@ data = rmt.recv_pulses() ## Constructors -#### class machine.RMT(channel,...) +### class machine.RMT(channel, ...) Construct an RMT object on the given channel. `channel` can be 2-7. With no additional parameters, the RMT object is created but not initialised. If extra arguments are given, the RMT is initialised for transmission or reception. See `init` for parameters of initialisation. The resolution which a pulse can be sent/received depends on the selected channel: @@ -56,7 +56,7 @@ Construct an RMT object on the given channel. `channel` can be 2-7. With no addi ## Methods -#### rmt.init(gpio, rx\_idle\_threshold, rx\_filter\_threshold, tx\_idle\_level, tx\_carrier) +### rmt.init(gpio, {rx_idle_threshold, [rx_filter_threshold]} / {tx_idle_level, [tx_carrier]}) Initialise the RMT peripheral with the given parameters: @@ -74,56 +74,37 @@ The `tx_carrier` parameter is a tuple with the following structure: * `carrier_duty_percent` is the duty percent of the carrier's signal, can be 0%-100%. * `carrier_level` is the level of the pulse to modulate, can be RMT.HIGH or RMT.LOW. -#### rmt.deinit() +### rmt.deinit() Deinitialise the RMT object. -{{% hint style="info" %}} -If an RMT object needs to be reconfigured from RX/TX to TX/RX, then either first `deinit()` must be called or the `init()` again with the desired configuration. -{{% /hint %}} +> If an RMT object needs to be reconfigured from RX/TX to TX/RX, then either first `deinit()` must be called or the `init()` again with the desired configuration. -#### rmt.pulses\_get(pulses, timeout) -Reads in pulses from the GPIO pin. +### rmt.pulses_get([pulses, timeout=MAX_DELAY]) -* `pulses` if not specified, this function will keep reading pulses until the +Reads in pulses from the GPIO pin. Can only be used in RX mode - `rx_idle_threshold` is exceeded. If it is specified this function will return +* `pulses` is the amount of pusles read, ignoring anything shorter than `rx_filter_threshold` or longer than `rx_idle_threshold`. if not specified, this function will keep reading pulses until the `rx_idle_threshold` is exceeded. - the exactly that number of pulses, ignoring anything shorter than - - `rx_filter_threshold` or longer than `rx_idle_threshold`. - -* `timeout` is specified, this function will return if the first pulse does - - not occur within `timeout` microseconds. If not specified, it will wait - - indefinitely. +* `timeout` is specified, this function will return if the first pulse does not occur within `timeout` microseconds. If not specified, it will wait indefinitely. Return value: Tuple of items with the following structure: `(level, duration)`: * `level` represents the level of the received bit/pulse, can be 0 or 1. * `duration` represents the duration of the received pulse, the time unit (resolution) depends on the selected channel. -{{% hint style="info" %}} -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) +> A 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. -Generates pulses as defined by the parameters below -* `duration` represents the duration of the pulses to be sent, +### rmt.pulses_send(duration, [data, start_level]) - the time unit (resolution) depends on the selected channel. +Generates pulses as defined by the parameters below. can only be used in TX mode -* `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. +* `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. diff --git a/content/firmwareapi/pycom/machine/rtc.md b/content/firmwareapi/pycom/machine/rtc.md index d2c8b73..6b32881 100644 --- a/content/firmwareapi/pycom/machine/rtc.md +++ b/content/firmwareapi/pycom/machine/rtc.md @@ -21,73 +21,62 @@ print(rtc.now()) ## Constructors -#### class machine.RTC(id=0, ...) +### class machine.RTC([id=0, ...]) 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) ``` ## Methods -#### rtc.init(datetime=None, source=RTC.INTERNAL\_RC) +### rtc.init([datetime=None, source=RTC.INTERNAL_RC]) 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]]]]])` -* `source` selects the oscillator that drives the RTC. The options are RTC.INTERNAL\_RC and RTC.XTAL\_32KHZ +* `source` selects the oscillator that drives the RTC. The options are + * `RTC.INTERNAL_RC`: Internal RC resonator + * `RTC.XTAL_32KHZ`: External 32KHz crystal For example: ```python - # for 2nd of February 2017 at 10:30am (TZ 0) rtc.init((2017, 2, 28, 10, 30, 0, 0, 0)) ``` -{{% hint style="info" %}} -`tzinfo` is ignored by this method. Use `time.timezone` to achieve similar results. -{{% /hint %}} +> `tzinfo` is ignored by this method. Use `time.timezone` to achieve similar results. -#### rtc.now() +### rtc.ntp_sync(server, [update_period=3600, backup_server]) -Get get the current `datetime` tuple: - -```python - -# returns datetime tuple -rtc.now() -``` - -#### rtc.ntp\_sync(server, \* , update\_period=3600) - -Set up automatic fetch and update the time using NTP (SNTP). +Inits the RTC and sets up up automatic fetch and update the time using NTP (SNTP). * `server` is the URL of the NTP server. Can be set to `None` to disable the periodic updates. * `update_period` is the number of seconds between updates. Shortest period is 15 seconds. +* `backup_server` is the URL of the backup NTP server. Can be set to `None` to disable the periodic updates. 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 ``` -#### rtc.synced() -Returns `True` if the last `ntp_sync` has been completed, `False` otherwise: +### rtc.now() -```python +Get get the current `datetime` tuple as `(year, month, day, hour, minute, second, usecond, None)` -rtc.synced() -``` -#### rtc.memory(\[data\]) +### rtc.synced() -Reads RTC memory contents or write data in passed Buffer in to RTC memory +Returns `True` if the last `ntp_sync` has been completed, `False` otherwise. + +### rtc.memory([data]) + +Reads RTC memory contents or write data in passed Buffer in to RTC memory. The buffer has space to store 2048 bytes. Example: diff --git a/content/firmwareapi/pycom/machine/sd.md b/content/firmwareapi/pycom/machine/sd.md index 434f72a..b69965b 100644 --- a/content/firmwareapi/pycom/machine/sd.md +++ b/content/firmwareapi/pycom/machine/sd.md @@ -10,11 +10,10 @@ The SD card class allows to configure and enable the memory card module of your `P8: DAT0`, `P23: SCLK` and `P4: CMD` (no external pull-up resistors are needed) -If you have one of the Pycom expansion boards, then simply insert the card into the micro SD socket and run your script. +If you have one of the Pycom expansion boards, then simply insert the card into the micro SD socket and run your script. + +> Make sure your SD card is formatted either as FAT16 or FAT32. -{{% hint style="info" %}} -Make sure your SD card is formatted either as FAT16 or FAT32. -{{% /hint %}} ## Quick Example Usage: @@ -40,20 +39,21 @@ f.close() ## Constructors -#### class machine.SD(id, ...) +### class machine.SD([id]) -Create a SD card object. See [`sd.init()`](../sd#sd-init-id-0) for parameters if initialisation. +Create a SD card object. See `sd.init()` for parameters. ## Methods -#### sd.init(id=0) +### sd.init([id=0]) -Enable the SD card. +Enable the SD card. The id is always 0. -#### sd.deinit() +> Use the [os](/firmwareapi/micropython/uos/) module to manipulate files. + +### sd.deinit() Disable the SD card. -{{% hint style="info" %}} -Please note that the SD card library currently supports FAT16/32 formatted SD cards up to 32 GB. Future firmware updates will increase compatibility with additional formats and sizes. -{{% /hint %}} +> Please note that the SD card library currently supports FAT16/32 formatted SD cards up to 32 GB. Future firmware updates will increase compatibility with additional formats and sizes. + diff --git a/content/firmwareapi/pycom/machine/spi.md b/content/firmwareapi/pycom/machine/spi.md index 6576c34..65ff055 100644 --- a/content/firmwareapi/pycom/machine/spi.md +++ b/content/firmwareapi/pycom/machine/spi.md @@ -50,13 +50,13 @@ spi.write_readinto(bytes([0x01, 0x02, 0x03, 0x04, 0x05]), rbuf) # send a receive ## Constructors -#### class machine.SPI(id, ...) +### class machine.SPI(id, ...) Construct an SPI object on the given bus. `id` can be only 0. With no additional parameters, the SPI object is created but not initialised (it has the settings from the last initialisation of the bus, if any). If extra arguments are given, the bus is initialised. See init for parameters of initialisation. ## Methods -#### spi.init(mode, baudrate=1000000, \* , polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO)) +### spi.init(mode, [baudrate=1000000, polarity=0, phase=0, bits=8, firstbit=SPI.MSB, pins=(CLK, MOSI, MISO)]) Initialise the SPI bus with the given parameters: @@ -68,23 +68,23 @@ Initialise the SPI bus with the given parameters: * `firstbit` can be SPI.MSB or SPI.LSB. * `pins` is an optional tuple with the pins to assign to the SPI bus. If the pins argument is not given the default pins will be selected (`P10` as CLK,`P11` as MOSI and `P14` as MISO). If pins is passed as None then no pin assignment will be made. -#### spi.deinit() +### spi.deinit() Turn off the SPI bus. -#### spi.write(buf) +### spi.write(buf) Write the data contained in `buf`. Returns the number of bytes written. -#### spi.read(nbytes, \* , write=0x00) +### spi.read(nbytes , [write=0x00]) Read the `nbytes` while writing the data specified by `write`. Returns the bytes read. -#### spi.readinto(buf, \* , write=0x00) +### spi.readinto(buf, [write=0x00]) Read into the buffer specified by `buf` while writing the data specified by `write`. Return the number of bytes read. -#### spi.write\_readinto(write\_buf, read\_buf) +### spi.write_readinto(write_buf, read_buf) Write from `write_buf` and read into `read_buf`. Both buffers must have the same length. Returns the number of bytes written diff --git a/content/firmwareapi/pycom/machine/timer.md b/content/firmwareapi/pycom/machine/timer.md index bb3fcd6..1fa8348 100644 --- a/content/firmwareapi/pycom/machine/timer.md +++ b/content/firmwareapi/pycom/machine/timer.md @@ -18,13 +18,13 @@ These two concepts are grouped into two different subclasses: You can create as many of these objects as needed. {{% /hint %}} -### Constructors +## Constructors -#### class Timer.Chrono() +### class Timer.Chrono() Create a chronometer object. -#### class Timer.Alarm(handler=None, s, \* , ms, us, arg=None, periodic=False) +### class Timer.Alarm([handler=None, {s, ms, us}, arg=None, periodic=False]) Create an Alarm object. @@ -35,7 +35,7 @@ Create an Alarm object. ### Methods -#### Timer.sleep\_us() +### Timer.sleep_us() Delay for a given number of microseconds, should be positive or 0 (for speed, the condition is not enforced). Internally it uses the same timer as the other elements of the `Timer` class. It compensates for the calling overhead, so for example, 100us should be really close to 100us. For times bigger than 10,000us it releases the GIL to let other threads run, so exactitude is not guaranteed for delays longer than that. @@ -43,29 +43,29 @@ Delay for a given number of microseconds, should be positive or 0 (for speed, th Can be used to measure time spans. -### Methods +## Methods -#### chrono.start() +### chrono.start() Start the chronometer. -#### chrono.stop() +### chrono.stop() Stop the chronometer. -#### chrono.reset() +### chrono.reset() Reset the time count to 0. -#### chrono.read() +### chrono.read() Get the elapsed time in seconds. -#### chrono.read\_ms() +### chrono.read_ms() Get the elapsed time in milliseconds. -#### chrono.read\_us() +### chrono.read_us() Get the elapsed time in microseconds. @@ -95,15 +95,15 @@ class Alarm – get interrupted after a specific interval Used to get interrupted after a specific interval. -### Methods +## Methods -#### alarm.callback(handler, \* , arg=None) +### alarm.callback(handler, [arg=None]) Specify a callback handler for the alarm. If set to `None`, the alarm will be disabled. An optional argument `arg` can be passed to the callback handler function. If `None` is specified, the function will receive the object that triggered the alarm. -#### alarm.cancel() +### alarm.cancel() Disables the alarm. @@ -127,6 +127,4 @@ class Clock: clock = Clock() ``` -{{% hint style="info" %}} -For more information on how Pycom's products handle interrupts, see [notes](/firmwareapi/notes#interrupt-handling). -{{% /hint %}} +> For more information on how Pycom's products handle interrupts, see [notes](/firmwareapi/notes#interrupt-handling). diff --git a/content/firmwareapi/pycom/machine/touch.md b/content/firmwareapi/pycom/machine/touch.md new file mode 100644 index 0000000..7998884 --- /dev/null +++ b/content/firmwareapi/pycom/machine/touch.md @@ -0,0 +1,36 @@ +--- +title: "Touch" +aliases: + - firmwareapi/pycom/machine/touch.html + - firmwareapi/pycom/machine/touch.md + - chapter/firmwareapi/pycom/machine/touch +--- + +The Touch module allows for certain GPIO pins (`P2`,`P3`,`P4`,`P6`,`P8`,`P9`,`P10`,`P19`,`P20`) to accept capacitive touch inputs. +A touch input is similar to a button, except for the lack of mechanical contact. The capacitive nature of touching a pad or pin will trigger a touch event. + +## Constructor + +### class machine.touch(pin) + +Create a touch object on pin. + +Example: +```python +touch = Touch('P9') +touch.read() +``` + +## Methods + +### touch.read() + +Reads the value of the touch pin + +### touch.config([sensitivity]) + +Set the threshold of the touchpad interrupt. Currently not used + +### touch.init_value() + +Currently not implemented diff --git a/content/firmwareapi/pycom/machine/uart.md b/content/firmwareapi/pycom/machine/uart.md index f611bf9..a9ecbae 100644 --- a/content/firmwareapi/pycom/machine/uart.md +++ b/content/firmwareapi/pycom/machine/uart.md @@ -73,7 +73,7 @@ uart.read(5) # read up to 5 bytes ## Constructors -#### class machine.UART(bus, ...) +### class machine.UART(bus, ...) Construct a UART object on the given `bus`. `bus` can be `0, 1 or 2`. If the `bus` is not given, the default one will be selected (`0`) or the selection will be made based on the given pins. @@ -83,7 +83,7 @@ On the GPy/FiPy UART2 is unavailable because it is used to communicate with the ## Methods -#### uart.init(baudrate=9600, bits=8, parity=None, stop=1, \* , timeout\_chars=2, pins=(TXD, RXD, RTS, CTS), rx\_buffer\_size=512) +### uart.init([baudrate=9600, bits=8, parity=None, stop=1, timeout_chars=2, pins=(TXD, RXD, RTS, CTS), rx_buffer_size=512]) Initialise the UART bus with the given parameters: @@ -95,49 +95,49 @@ Initialise the UART bus with the given parameters: * `pins` is a 4 or 2 item list indicating the TXD, RXD, RTS and CTS pins (in that order). Any of the pins can be `None` if one wants the UART to operate with limited functionality. If the RTS pin is given the the RX pin must be given as well. The same applies to CTS. When no pins are given, then the default set of TXD (P1) and RXD (P0) pins is taken, and hardware flow control will be disabled. If `pins=None`, no pin assignment will be made. * `rx_buffer_size` is the size of the buffer used for storing the RX packets. By default is is 512 bytes. -#### uart.deinit() +### uart.deinit() Turn off the UART bus. -#### uart.any() +### uart.any() Return the number of characters available for reading. -#### uart.read(\[nbytes\]) +### uart.read([nbytes]) Read characters. If `nbytes` is specified then read at most that many bytes. Return value: a bytes object containing the bytes read in. Returns `None` on timeout. -#### uart.readall() +### uart.readall() Read as much data as possible. Return value: a bytes object or `None` on timeout. -#### uart.readinto(buf\[, nbytes\]) +### uart.readinto(buf, [nbytes]) Read bytes into the `buf`. If `nbytes` is specified then read at most that many bytes. Otherwise, read at most `len(buf)` bytes. Return value: number of bytes read and stored into `buf` or `None` on timeout. -#### uart.readline() +### uart.readline() Read a line, ending in a newline character. If such a line exists, return is immediate. If the timeout elapses, all available data is returned regardless of whether a newline exists. Return value: the line read or `None` on timeout if no data is available. -#### uart.write(buf) +### uart.write(buf) Write the buffer of bytes to the bus. Return value: number of bytes written or None on timeout. -#### uart.sendbreak() +### uart.sendbreak() Send a break condition on the bus. This drives the bus low for a duration of 13 bits. Return value: `None`. -#### uart.wait\_tx\_done(timeout\_ms) +### uart.wait_tx_done(timeout_ms) Waits at most `timeout_ms` for the last Tx transaction to complete. Returns `True` if all data has been sent and the TX buffer has no data in it, otherwise returns `False`. diff --git a/content/firmwareapi/pycom/machine/wdt.md b/content/firmwareapi/pycom/machine/wdt.md index a87ea39..b1df91f 100644 --- a/content/firmwareapi/pycom/machine/wdt.md +++ b/content/firmwareapi/pycom/machine/wdt.md @@ -19,17 +19,17 @@ wdt.feed() ## Constructors -#### class machine.WDT(id=0, timeout) +### class machine.WDT(id=0, timeout) Create a WDT object and start it. The `id` can only be `0`. See the init method for the parameters of initialisation. ## Methods -#### wdt.init(timeout) +### wdt.init(timeout) Initialises the watchdog timer. The timeout must be given in milliseconds. Once it is running the WDT cannot be stopped but the timeout can be re-configured at any point in time. -#### wdt.feed() +### wdt.feed() Feed the WDT to prevent it from resetting the system. The application should place this call in a sensible place ensuring that the WDT is only fed after verifying that everything is functioning correctly. diff --git a/content/firmwareapi/pycom/network/bluetooth/_index.md b/content/firmwareapi/pycom/network/bluetooth/_index.md index 166cbc5..0542c6c 100644 --- a/content/firmwareapi/pycom/network/bluetooth/_index.md +++ b/content/firmwareapi/pycom/network/bluetooth/_index.md @@ -60,35 +60,38 @@ bluetooth = Bluetooth() ## Methods -#### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None, modem\_sleep=True, pin=None, privacy=True, secure\_connections=True, mtu=200) +### bluetooth.init([id=0, mode=Bluetooth.BLE, antenna=Bluetooth.INT_ANT, modem_sleep=True, pin=None, privacy=True, secure_connections=True, mtu=200]) -* `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 `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`. -* `modem_sleep` Enables or Disables BLE modem sleep, Disable modem sleep as a workaround when having Crashes due to flash cache being disabled, as this prevents BLE task saving data in external RAM while accesing external flash for R/W. -* `pin` a one to six digit number (`0`-`9`) to connect to the GATT Sever. Setting any valid pin, GATT Server security features are activated. + +* `id` Only one Bluetooth peripheral available so must always be 0 +* `mode` currently the only supported mode is `Bluetooth.BLE` +* `modem_sleep` Enables or Disables BLE modem sleep, Disable modem sleep as a workaround when having Crashes due to flash cache being disabled, as this prevents BLE task saving data in external RAM while accesing external flash for R/W +* `antenna` selects between the internal and the external antenna. Can be either: + * `Bluetooth.INT_ANT` + * `Bluetooth.EXT_ANT` +* `secure` enables or disables the GATT Server security feature +* `pin` a six digit number to connect to the GATT Sever Setting any valid pin, GATT Server security features are activated. * `privacy` Enables or Disables local privacy settings so address will be random or public. * `secure_connections` Enables or Disables Secure Connections and MITM Protection. * `mtu` Maximum Transmission Unit (MTU) is the maximum length of an ATT packet. Value must be between `23` and `200`. -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. 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. -{{% hint style="info" %}} To use an external antenna, set `P12 as output pin.` ```python Pin('P12', mode=Pin.OUT)(True) ``` -{{% /hint %}} -#### bluetooth.deinit() + +### 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. @@ -103,15 +106,15 @@ 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)` @@ -133,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`. @@ -167,11 +170,11 @@ while bluetooth.isscanning(): print(ubinascii.hexlify(mfg_data)) ``` -#### bluetooth.set\_pin() +### bluetooth.set_pin() Configures a new PIN to be used by the device. The PIN is a 1-6 digit length decimal number, if less than 6 digits are given the missing leading digits are considered as 0. E.g. 1234 becomes 001234. When a new PIN is configured, the information of all previously bonded device is removed and the current connection is terminated. To restart advertisement the advertise() must be called after PIN is changed. -#### bluetooth.connect(mac\_addr, timeout=None) +### bluetooth.connect(mac_addr, [timeout=None]) * `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`. @@ -180,7 +183,7 @@ Configures a new PIN to be used by the device. The PIN is a 1-6 digit length dec 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: @@ -190,7 +193,7 @@ 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. @@ -214,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. @@ -231,7 +234,7 @@ Example: bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1") ``` -#### bluetooth.set\_advertisement\_params(\* , adv\_int\_min=0x20, adv\_int\_max=0x40, adv\_type=Bluetooth.ADV\_TYPE\_IND, own\_addr\_type=Bluetooth.BLE\_ADDR\_TYPE\_PUBLIC, channel\_map=Bluetooth.ADV\_CHNL\_ALL, adv\_filter\_policy=Bluetooth.ADV\_FILTER\_ALLOW\_SCAN\_ANY\_CON\_ANY) +### bluetooth.set_advertisement_params(adv_int_min=0x20, adv_int_max=0x40, adv_type=Bluetooth.ADV_TYPE_IND, own_addr_type=Bluetooth.BLE_ADDR_TYPE_PUBLIC, channel_map=Bluetooth.ADV_CHNL_ALL, adv_filter_policy=Bluetooth.ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY) Configure the parameters used when advertising. @@ -244,11 +247,11 @@ The arguments are: * `channel_map` is the advertising channel map. * `adv_filter_policy` is the advertising filter policy. -#### 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`. @@ -263,11 +266,11 @@ The arguments are: bluetooth.service('abc123') ``` -#### bluetooth.disconnect\_client() +### bluetooth.disconnect_client() Closes the BLE connection with the client. -### bluetooth.tx\_power(type, level) +### bluetooth.tx_power(type, level) Gets or sets the TX Power level. If called with only `type` parameter it returns with the current value belonging to the given type. diff --git a/content/firmwareapi/pycom/network/bluetooth/btmesh.md b/content/firmwareapi/pycom/network/bluetooth/btmesh.md new file mode 100644 index 0000000..80069b5 --- /dev/null +++ b/content/firmwareapi/pycom/network/bluetooth/btmesh.md @@ -0,0 +1,116 @@ +--- +title: "Pymesh BLE" +aliases: + - firmwareapi/pycom/network/bluetooth/BLE_Mesh.html + - firmwareapi/pycom/network/bluetooth/BLE_Mesh.md +--- + +The Pymesh BLE library provides support for connecting to a BLE Mesh Network with various Server and Client models. + +For examples, please check the section [Pymesh BLE Examples](/tutorials/networkprotocols/ble_mesh/). + +Pymesh BLE features: + +* Supported Models: + * Configuration Server Model (automatically generated together with primary Element) + * Generic OnOff Server Model + * Generic OnOff Client Model + * Generic Level Server Model + * Generic Level Client Model + * Sensor Server Model + * Sensor Client Model +* Supported OOB authentication types: + * No OOB + * Output OOB +* Supported Node Features: + * GATT Proxy + * Relay +* Only one Element (primary) can be added to the Node. +* Node cannot be configured as Provisioner and a mobile application should be used for Provisioning process + * nRF Mesh (iOS and Android) + * Silicon Labs Bluetoth Mesh (iOS) + * ST BLE Mesh (Android) + * EspBLEMesh (Android) + + +## Methods of BLE_Mesh class + +### BLE_Mesh.init(name="PYCOM-ESP-BLE-MESH", *, auth=0, callback=None) + +Initializes the BLE Mesh module with the pre-configured Elements and Models. + +* `name` is the name which will be used to identify the device during Provisioning +* `auth` is the Out-Of-Band (OOB) method. Currently `BLE_Mesh.OOB_OUTPUT` is supported. Without specifying this argument, `NO_OOB` will be used during provisioning. +* `callback` is the callback to be registered. It must have the following arguments: + * `event` returns current event of provisioning. + * `oob_pass` returns the generated pass in case of `BLE_Mesh.OOB_OUTPUT`. + +### BLE_Mesh.set_node_prov(bearer=BLE_Mesh.PROV_NONE, *) + +Enable provisioning bearers to get the device ready for provisioning. If OOB is enabled, the callback is used to inform the user about OOB information. + +* `bearer` is the transport data protocol between endpoints, can be `BLE_Mesh.PROV_ADV` and/or `BLE_Mesh.PROV_GATT`. + +### BLE_Mesh.reset_node_prov() + +Resets the Node Provisioning information. + +### BLE_Mesh.create_element(*, primary, feature=0, beacon=true, ttl=7) + +This API creates a new BLE_Mesh_Element object. The BLE_Mesh_Element on concept level is equivalent to the Element in the BLE Mesh terminology. + +* `primary` shows whether this new Element will act as the Primary Element of the Node. When a Primary Element is created, the corresponding Configuration Server Model is also automatically created. There can only be 1 Primary Element per Node. +* `feature` shows what features to enable on the new Element. It is an ORED combination of `BLE_Mesh.RELAY`, `BLE_Mesh.LOW_POWER`, `BLE_Mesh.GATT_PROXY`, `BLE_Mesh.FRIEND` +* `ttl` is the default Time To Live value of the packets belonging to the new Element + +## Methods of BLE_Mesh_Element object + +### BLE_Mesh_Element.add_model(type=BLE_Mesh.GEN_ONOFF, server_client=BLE_Mesh.SERVER, *, callback=None, value=None, sen_min=-100, sen_max=100, sen_res=0.1) + +This API creates a new BLE_Mesh_Model object. The BLE_Mesh_Model on concept level is equivalent to the Model in the BLE Mesh terminology. + +* `type` is the type of the new Model. +* `server_client` shows whether the new Model will act as a Server or Client. +* `callback` is the user defined callback to call when any event happens on the Model. It accepts 3 parameters: `new_state`, `event`, `op_code`. The `new_state` is the corresponding state of BLE_Mesh_Model, the `event` and the `op_code` are belonging of the BLE Mesh packet received. +* `value` is the initial value represented by the Model. +* `sen_min` is the minimum value of Sensor State in case of Sensor Model. +* `sen_max` is the maximum value of Sensor State in case of Sensor Model. +* `sen_res` is the resolution of Sensor State in case of Sensor Model. + +## Methods of BLE_Mesh_Model object + +### BLE_Mesh_Model.get_state(addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None) + +Gets the State of the Sensor Model. If called from Server Model, returnes with State, in case of Client Model, it sends a Get Message, and returns State through the registered callback. + +* `addr` is the address of the remote Node to send the update message. +* `app_idx` is the index of one of the registered Application IDs to use when sending out the message. +* `state_type` is the type of Get State. + +### BLE_Mesh_Model.set_state(state, addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None) + +Sets the State of the Sensor Model. If called from Server Model, sets State directly, in case of Client Model, it sends a Set Message, and updates State. + +* `state` is the new value to update the current value with. +* `addr` is the address of the remote Node to send the update message. +* `app_idx` is the index of one of the registered Application IDs to use when sending out the message. +* `state_type` is the type of Set State. + +### BLE_Mesh_Model.status_state(addr=BLE_Mesh.ADDR_ALL_NODES, app_idx=0, state_type=None) + +Calling this function only makes sense when the BLE_Mesh_Model is a Server Model. It sends a Status message with the State to the Client Model(s). + +* `addr` is the address of the remote Node to send the update message. +* `app_idx` is the index of one of the registered Application IDs to use when sending out the message. +* `state_type` is the type of Status State. + +## Constants + +* Advertisement options: `BLE_Mesh.PROV_ADV`, `BLE_Mesh.PROV_GATT`, `BLE_Mesh.PROV_NONE` +* Features of an Element: `BLE_Mesh.RELAY`, `BLE_Mesh.LOW_POWER`, `BLE_Mesh.GATT_PROXY`, `BLE_Mesh.FRIEND` +* Authentication options: `BLE_Mesh.OOB_INPUT`, `BLE_Mesh.OOB_OUTPUT` +* Constants for Node addresses: `BLE_Mesh.ADDR_ALL_NODES`, `BLE_Mesh.ADDR_PUBLISH` +* Constants for Model - type: `BLE_Mesh.GEN_ONOFF`, `BLE_Mesh.GEN_LEVEL`, `BLE_Mesh.GEN_SENSOR`, `BLE_Mesh.GEN_SENSOR_SETUP` +* Constants for Model - server or client: `BLE_Mesh.SERVER`, `BLE_Mesh.CLIENT` +* Constants for Model - states: `BLE_Mesh.STATE_ONOFF`, `BLE_Mesh.STATE_LEVEL`, `BLE_Mesh.STATE_LEVEL_DELTA`, `BLE_Mesh.STATE_LEVEL_MOVE`, `BLE_Mesh.SEN_DESCRIPTOR`, `BLE_Mesh.SEN`, `BLE_Mesh.SEN_COLUMN`, `BLE_Mesh.SEN_SERIES`, `BLE_Mesh.SEN_SET_CADENCE`, `BLE_Mesh.SEN_SETTINGS`, `BLE_Mesh.SEN_SETTING` +* Constants for Provision Events: `BLE_Mesh.PROV_REGISTER_EVT`, `BLE_Mesh.PROV_ENABLE_EVT`, `BLE_Mesh.PROV_DISABLE_EVT`, `BLE_Mesh.LINK_OPEN_EVT`, `BLE_Mesh.LINK_CLOSE_EVT`, `BLE_Mesh.PROV_COMPLETE_EVT`, `BLE_Mesh.PROV_RESET_EVT`, `BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT`, `BLE_Mesh.PROV_INPUT_OOB_REQ_EVT` \ No newline at end of file diff --git a/content/firmwareapi/pycom/network/coap.md b/content/firmwareapi/pycom/network/coap.md index 6c503f6..120aaad 100644 --- a/content/firmwareapi/pycom/network/coap.md +++ b/content/firmwareapi/pycom/network/coap.md @@ -83,7 +83,7 @@ print(id) ## Initialization -#### Coap.init(address, *, port=5683, service_discovery=False) +### Coap.init(address, *, port=5683, service_discovery=False) Initialize the CoAp module. @@ -95,11 +95,11 @@ The arguments are: ## Methods: -#### Coap.socket() +### Coap.socket() Returns with the socket assigned to the given address and port during Coap.init() (= assigned to the CoAp module). -#### Coap.add_resource(uri, *, media_type=-1, max_age=-1, value=0, etag=False) +### Coap.add_resource(uri, *, media_type=-1, max_age=-1, value=0, etag=False) Creates a resource object and adds it to the CoAp module to operate as a server. @@ -110,32 +110,28 @@ Creates a resource object and adds it to the CoAp module to operate as a server. * `etag` is a Boolean argument that enables/disables entity tag calculation (CoAp option: ETag). By default it is turned off. -{{% hint style="info" %}} -Media-type argument is one of the standard defined values that is available via CoAp module's constants. -{{% /hint %}} +> Media-type argument is one of the standard defined values that is available via CoAp module's constants. -{{% hint style="info" %}} -Entity tag calculation is a simple counter increment between value 1-65535 with overflow, it doesn't include the value 0. It is incremented each time and the value of the resource is changed. -{{% /hint %}} +> Entity tag calculation is a simple counter increment between value 1-65535 with overflow, it doesn't include the value 0. It is incremented each time and the value of the resource is changed. -#### Coap.remove_resource(uri) +### Coap.remove_resource(uri) Removes the resource defined by the `uri` argument. * `uri` is the full path of the resource to be removed. -#### Coap.get_resource(uri) +### Coap.get_resource(uri) Returns with the resource defined by `uri` argument. * `uri` is the full path of the resource to be returned. -#### Coap.read() +### Coap.read() Must be called when a packet is received on the socket assigned to the CoAp module. This function passes on the incoming request, whilst also composing and sending out the response if needed. -#### Coap.register_response_handler(callback) +### Coap.register_response_handler(callback) Registers a callback function which will be called when a remote CoAp Server responses to the local CoAp client's request. @@ -146,7 +142,7 @@ Registers a callback function which will be called when a remote CoAp Server res * `token` is the token field from the received message * `payload` is the payload of the received message -#### Coap.send_request(uri_host, method, *, uri_port=5683, uri_path, content_format, payload, token, include_options=true) +### Coap.send_request(uri_host, method, *, uri_port=5683, uri_path, content_format, payload, token, include_options=true) Creates and sends a request to a CoAp server. @@ -163,11 +159,8 @@ Creates and sends a request to a CoAp server. The resource class represents a resource in the scope of the CoAp module when acting as a server. A new resource can only be created with the `Coap.add_resource` function. -#### Class methods -The following methods are defined in the scope of the `resource` class. - -#### resource.add_attribute(name, value) +### resource.add_attribute(name, value) Adds a new attribute to the resource. Attributes are used to explain the resource during service discovery. @@ -184,31 +177,28 @@ coap-client -m get coap:///.well-known/core {{% /hint %}} -#### resource.value(value) +### resource.value(value) Updates or fetches the value of the resource. * `value` is the new value to update the current value with. If the method is called without a parameter, the current value is returned. -#### resource.callback(operation, enable) +### resource.callback(operation, enable) To enable or disable a specific operation (GET, PUT, POST, DELETE) on the resource. * `operation` is the operation to enable/disable, can be ORED of the followings: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE` * `enable` is Boolean parameter that enables/disables the operations specified by `operation` -{{% hint style="info" %}} -During a GET request, only the first occurrence of an ETAG or Accept option is passed on and interpreted; others of the same type are dropped (if any). -{{% /hint %}} +> During a GET request, only the first occurrence of an ETAG or Accept option is passed on and interpreted; others of the same type are dropped (if any). -{{% hint style="info" %}} -During a PUT request, only the first occurrence of an If-Match option is passed on and interpreted; others of the same type are dropped (if any). -{{% /hint %}} +> During a PUT request, only the first occurrence of an If-Match option is passed on and interpreted; others of the same type are dropped (if any). + + + +> Due to limitations of the underlying ESP-IDF/libcoap library, new resources cannot be added via PUT or POST requests. -{{% hint style="danger" %}} -Due to limitations of the underlying ESP-IDF/libcoap library, new resources cannot be added via PUT or POST requests. -{{% /hint %}} ## Constants diff --git a/content/firmwareapi/pycom/network/eth.md b/content/firmwareapi/pycom/network/eth.md index 2e307de..73c3e9f 100644 --- a/content/firmwareapi/pycom/network/eth.md +++ b/content/firmwareapi/pycom/network/eth.md @@ -21,7 +21,7 @@ The PyEthernet board is connected via SPI bus 3 and GPIO's 17-19 and 21-23. So t ## Constructors -### class network.ETH(id=0, ...) +### class network.ETH([id=0], ...) Create and configure an ETH object. See init for params of configuration. @@ -33,25 +33,22 @@ eth = ETH() ## Methods -### eth.init(hostname=None) +### eth.init([hostname=None]) This function starts the Ethernet interface and enables the ethernet adapter. `hostname`: set the interface hostname -### eth.ifconfig(config=\['dhcp' or configtuple\]) +### eth.ifconfig([config={'dhcp' / configtuple}]) -With no parameters given, this returns a 4-tuple of (ip, subnet mask, gateway, DNS server). +Get or set the interface configuration. Optionally specify the configuration parameter: -- `config='dhcp'` +* `config='dhcp'`: If 'dhcp' is passed as a parameter, then the DHCP client is enabled and the IP parameters are negotiated with the DHCP server. +* `config=(ip, nm, gw, dns)`: If the 4-tuple config is given then a static IP is configured. -If 'dhcp' is passed as a parameter, then the DHCP client is enabled and the IP parameters are negotiated with the DHCP server. - -- `config=(ip, nm, gw, dns)` - -If the 4-tuple config is given then a static IP is configured. For example: `eth.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))`. +For example: `eth.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))`. ### eth.hostname(string) diff --git a/content/firmwareapi/pycom/network/lora.md b/content/firmwareapi/pycom/network/lora.md deleted file mode 100644 index 7d930de..0000000 --- a/content/firmwareapi/pycom/network/lora.md +++ /dev/null @@ -1,523 +0,0 @@ ---- -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/_index.md b/content/firmwareapi/pycom/network/lora/_index.md index 5042da5..eff3f63 100644 --- a/content/firmwareapi/pycom/network/lora/_index.md +++ b/content/firmwareapi/pycom/network/lora/_index.md @@ -3,58 +3,17 @@ title: "LoRa" aliases: - /firmwareapi/pycom/network/lora.md --- -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: +This class provides a LoRaWAN 1.0.2 compliant driver for the LoRa network processor in the LoPy, LoPy4 and FiPy. -```python -from network import LoRa -import socket -import ubinascii -import struct +> 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. -# 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) +## Examples -# 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. +For various complete LoRa examples, check [here](/tutorials/networks/lora/). ## Constructors -#### class network.LoRa(id=0, ...) +### class network.LoRa(...) Create and configure a LoRa object. See init for params of configuration. @@ -64,199 +23,107 @@ 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) +### lora.init(mode, [region=LoRa.EU868, frequency, tx_power, 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=2, 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`. +* `mode` can be either + * `LoRa.LORA`: For LoRa MAC / RAW + * `LoRa.LORAWAN`: For use in the LoRa Wide Area Network and services like TTN and Chirpstack +* `region` can take the following values: + * `LoRa.AS923` + * `LoRa.AU915` + * `LoRa.EU868` + * `LoRa.US915` + * `LoRa.CN470` + * `LoRa.IN865` + + > If no region is provided, it will default to the setting provided in the CONFIG partition, set by the Firmware Updater tool. +* `frequency` accepts values within the selected Region frequency bands. +* `tx_power` is the transmit power in dBm. +* `bandwidth` is the channel bandwidth in KHz. + * `LoRa.BW_125KHZ` + * `LoRa.BW_250KHZ` + * `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. +* `coding_rate` can take the following values: + * `LoRa.CODING_4_5` + * `LoRa.CODING_4_6` + * `LoRa.CODING_4_7` + * `LoRa.CODING_4_8` +* `power_mode` can be either + * `LoRa.ALWAYS_ON`: the radio is always listening for incoming - packets whenever a transmission is not taking place + * `LoRa.TX_ONLY`: he radio goes to sleep as soon as the transmission completes + * `LoRa.SLEEP`: 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`. +* `device_class` sets the LoRaWAN device class. Can be either: + * `LoRa.CLASS_A` + * `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 %}} +> 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. -For example, you can do: +### lora.join(activation, auth, [timeout=None, dr=None]) -```python -# initialize in raw LoRa mode -lora.init(mode=LoRa.LORA, tx_power=14, sf=12) -``` +Join a LoRaWAN network. Internally the stack will automatically retry every 15 seconds until a Join Accept message is received. The parameters are: -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`. +* `activation`: can be either: + * `LoRa.OTAA`: Over the Air Activation + * `LoRa.ABP`: Activation By Personalisation * `auth`: is a tuple with the authentication data. + * 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. + * In the case of `LoRa.ABP` the authentication tuple is: `(dev_addr, nwk_swkey, app_swkey)`. * `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**. +* `dr`: is an optional value to specify the initial data rate for the Join Request. values are region specific. -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 -``` +### lora.frequency([frequency]) -or +Get or set the frequency in raw LoRa mode (`LoRa.LORA`). The allowed range is region-specific. -```python -lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # a custom DEV_EUI is specified -``` +### lora.bandwidth([bandwidth]) -Example: +Get or set the bandwidth in raw LoRa mode (`LoRa.LORA`). Bandwidth can be either: (depending on the region setting) +* `LoRa.BW_125KHZ` +* `LoRa.BW_250KHZ` +* `LoRa.BW_500KHZ` -```python -from network import LoRa -import socket -import time -import ubinascii +### lora.coding_rate([coding_rate]) -# 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) +Get or set the coding rate in raw LoRa mode (`LoRa.LORA`). The allowed values are: (depending on the region setting) +* `LoRa.CODING_4_5` +* `LoRa.CODING_4_6` +* `LoRa.CODING_4_7` +* `LoRa.CODING_4_8` -# 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) +### lora.preamble([preamble]) -# wait until the module has joined the network -while not lora.has_joined(): - time.sleep(2.5) - print('Not yet joined...') -``` +Get or set the number of preamble symbols in raw LoRa mode (`LoRa.LORA`). -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\]) +### 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() +### lora.power_mode([power_mode]) -# set raw LoRa spread factor value -lora.sf(7) -``` +Get or set the power mode in raw LoRa mode (`LoRa.LORA`). The accepted values are: +* `LoRa.ALWAYS_ON` +* `LoRa.TX_ONLY` +* `LoRa.SLEEP` -#### 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() +### 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. @@ -270,11 +137,11 @@ Where: * `tx_counter` is the number of packets transmitted. * `tx_frequency` is the frequency used for the last transmission. -#### lora.has\_joined() +### lora.has_joined() Returns `True` if a LoRaWAN network has been joined. `False` otherwise. -#### lora.add\_channel(index, \* , frequency, dr\_min, dr\_max) +### 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. @@ -285,13 +152,13 @@ The arguments are: * `dr_min`: Minimum data rate of the channel (0-7). * `dr_max`: Maximum data rate of the channel (0-7). -Examples: +Example: ```python lora.add_channel(index=0, frequency=868000000, dr_min=5, dr_max=6) ``` -#### lora.remove\_channel(index) +### 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: @@ -299,21 +166,20 @@ Removes the channel from the specified `index`. On the 868MHz band the channels lora.remove_channel() ``` -On the 915MHz band there are no restrictions around this. - -#### lora.mac() +### lora.mac() Returns a byte object with the 8-Byte MAC address of the LoRa radio. -#### lora.callback(trigger, handler=None, arg=None) +### 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. +Specify a callback handler for the LoRa radio. The `trigger` types are +* `LoRa.RX_PACKET_EVENT` is raised for every received packet +* `LoRa.TX_PACKET_EVENT` is raised as soon as the packet transmission cycle ends, which includes the end of the receive windows. 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. +* `LoRa.TX_FAILED_EVENT` will be raised after the number of `tx_retries` configured have been performed and no `ack` is received. An example of how this callback functions can be seen the in method [`lora.events()`](../lora#lora-events). -#### lora.ischannel\_free(rssi\_threshold) +### 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: @@ -321,7 +187,7 @@ This method is used to check for radio activity on the current LoRa channel, and lora.ischannel_free(-100) ``` -#### lora.set\_battery\_level(level) +### 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: @@ -333,7 +199,7 @@ Set the battery level value that will be sent when the LoRaWAN MAC command that lora.set_battery_level(127) # 50% battery ``` -#### lora.events() +### 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. @@ -350,7 +216,7 @@ def lora_cb(lora): lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=lora_cb) ``` -#### lora.nvram\_save() +### 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. @@ -358,39 +224,20 @@ Save the LoRaWAN state (joined status, network keys, packet counters, etc) in no lora.nvram_save() ``` -#### lora.nvram\_restore() +### 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() +### lora.nvram_erase() Remove the LoRaWAN state (joined status, network keys, packet counters, etc) from non-volatile memory. -```python -lora.nvram_erase() -``` -#### lora.nvram\_erase() - -Remove the LoRaWAN state (joined status, network keys, packet counters, etc) from non-volatile memory. - -```python -lora.nvram_erase() -``` - -#### lora.mesh() +### lora.mesh() Enable the Mesh network. Only after Mesh enabling the `lora.cli()` and `socket` can be used. -```python -lora.mesh() -``` - -#### lora.cli() +### lora.cli() Send OpenThread CLI commands, the list is [here](https://github.com/openthread/openthread/blob/master/src/cli/README). The output is multiline string, having as line-endings the `\r\n`. @@ -430,107 +277,4 @@ And they must be created after initialising the LoRa network card. LoRa-Mesh socket is created, if the Mesh was enabled before (`lora.mesh()` was called). -{{% hint style="info" %}} -The LoRa-Mesh socket supports only the following socket methods: `close()` , `bind()`, `sendto()`, and `recvfrom()`. -{{% /hint %}} - -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.sendto(bytes,(ip, port)) - -This is supported only by the LoRa Mesh socket. - -Usage: - -```python -s.sendto('Hello', ('fdde:ad00:beef:0:0:ff:fe00:e800', 1234)) -``` - -#### 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) -``` +> The LoRa-Mesh socket supports only the following socket methods: `close()` , `bind()`, `sendto()`, and `recvfrom()`. diff --git a/content/firmwareapi/pycom/network/lte.md b/content/firmwareapi/pycom/network/lte.md index 9807931..5d331ac 100644 --- a/content/firmwareapi/pycom/network/lte.md +++ b/content/firmwareapi/pycom/network/lte.md @@ -13,17 +13,10 @@ The GPy and FiPy support both new LTE-M protocols: * **Cat-M1**: also known as **LTE-M** defines a 1.4 MHz radio channel size and about 375 kbps of throughput. It is optimised for coverage and long battery life, outperforming 2G/GPRS, while being similar to previous LTE standards. * **Cat-NB1** also known as **NB-IoT**, defines a 200 kHz radio channel size and around 60 kbps of uplink speed. It's optimised for ultra low throughput and specifically designed for IoT devices with a very long battery life. NB-IoT shares some features with LTE such as operating in licensed spectrum, but it's a very different protocol. It should be noted that NB-IoT has many restrictions as does not offer full IP connectivity and does not support mobility. When moving between cells, you will need to reconnect. -{{% hint style="info" %}} -**Please note:** The GPy and FiPy only support the two protocols above and are not compatible with older LTE standards. -{{% /hint %}} +> 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](/updatefirmware/ltemodem/). -{{% 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). -{{% /hint %}} -{{% hint style="info" %}} - -**FiPy/Gpy Band Support** +## Band support - Fipy/GPy v1.0 ==> supports 6 bands only (3, 4, 12, 13, 20, 28) @@ -33,7 +26,6 @@ The Sequans modem used on Pycom's cellular enabled modules can only work in one - Fipy/GPy v1.2 with Sequans old modem Firmwares < (39xxx)==> Supports 6 Bands (3, 4, 12, 13, 20, 28) -{{% /hint %}} ## AT Commands @@ -42,7 +34,7 @@ The AT commands for the Sequans Monarch modem on the GPy/FiPy are available in a ## Constructors -#### class network.LTE(id=0, ...) +### class network.LTE(id=0, ...) Create and configure a LTE object. See init for params of configuration. @@ -54,158 +46,143 @@ lte = LTE() ## Methods -#### lte.init(\*, carrier=None) +### lte.init([carrier='standard', psm_period_value=0, psm_period_unit=LTE.PSM_PERIOD_DISABLED, psm_active_value=0, psm_active_unit=LTE.PSM_ACTIVE_DISABLED]) -This method is used to set up the LTE subsystem. After a `deinit()` this method can take several seconds to return waiting for the LTE modem to start-up. Optionally specify a carrier name. The available options are: `verizon, at&t, standard`. `standard` is generic for any carrier, and it's also the option used when no arguments are given. +This method is used to set up the LTE subsystem. Optionally specify +* `carrier name`. The available options are: + * `'at&t'` + * `'verizon'` + * `'standard'` +* `psm_period_value` : Configure at which period the device will connect to the network. Values from 0 to 31 are allowed +* `psm_period_unit` : Specify the _unit_ to be used for `psm_period_value`: + * `PSM_PERIOD_2S` + * `PSM_PERIOD_30S` + * `PSM_PERIOD_1M` + * `PSM_PERIOD_1H` + * `PSM_PERIOD_10H` + * `PSM_PERIOD_320H` + * `PSM_PERIOD_DISABLED`: Turn off the PSM mode. +* `psm_active_value` : Configure how long the device will be connected. Values from 0 to 31 are allowed. +* `psm_active_unit` : Specify the _unit_ for `psm_active_value`: + * `PSM_ACTIVE_2S` + * `PSM_ACTIVE_1M` + * `PSM_ACTIVE_6M` + * `PSM_ACTIVE_DISABLED`: turn off the PSM mode. -#### lte.deinit(detach=True, reset = False) +Multiply the `value` with the `unit` to get the actual active or sleeping times. + +### lte.deinit([detach=True, reset=False]) Disables LTE modem completely. This reduces the power consumption to the minimum. Call this before entering deepsleep. -- `detach` : detach from network. +* `detach` : detach from network. +* `reset` : reset LTE modem. -- `reset` : reset LTE modem. +### lte.psm() -#### lte.attach(\*, band=None, apn=None, cid=None, type=LTE.IP, legacyattach=True) +Queries the PSM timers. Returns a 5-tuple of the following structure: `(enabled, period_value, period_unit, active_value, active_unit)`. + +### 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`. +* `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 +* `type` : PDP context type either `LTE.IP` or `LTE.IPV4V6`. These are options to specify PDP type ‘Packet Data protocol' either IP [Internet Protocol] or IPV4V6 ver4,6 , that depends actually on what does the Network support. +* `legacyattach` : When kept = True the API `LTE.isattached()` will return True when attached to the Network AND Network registration status is home or roaming, when flag is False, API `LTE.isattached()` will return True when attached to the Network only. -- `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 -- `type` : PDP context type either `LTE.IP` or `LTE.IPV4V6`. These are options to specify PDP type ‘Packet Data protocol' either IP [Internet Protocol] or IPV4V6 ver4,6 , that depends actually on what does the Network support. - -- `legacyattach` : When kept = True the API `LTE.isattached()` will return True when attached to the Network AND Network registration status is home or roaming, when flag is False, API `LTE.isattached()` will return True when attached to the Network only. - ---- -*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() +### lte.isattached() Returns `True` if the cellular mode is attached to the network. `False` otherwise. -#### lte.detach(reset=False) +### lte.detach([reset=False]) Detach the modem from the LTE Cat M1 and disable the radio functionality. -- `reset` : set to True to reset the LTE modem. +* `reset` : set to True to reset the LTE modem. -#### lte.connect(\*, cid=1) +### lte.connect([cid=1]) Start a data session and obtain and IP address. Optionally specify a CID (Connection ID) for the data session. The arguments are: * `cid` is a Connection ID. This is carrier specific, for Verizon use `cid=3`. For others like Telstra it should be `cid=1`. -For instance, to attach and connect to Verizon: - -```python - -import time -from network import LTE - -lte = LTE(carrier="verizon") -lte.attach(band=13) - -while not lte.isattached(): - time.sleep(0.5) - print('Attaching...') - -lte.connect(cid=3) -while not lte.isconnected(): - time.sleep(0.5) - print('Connecting...') - -# Now use sockets as usual... -``` - -#### lte.isconnected() +### lte.isconnected() Returns `True` if there is an active LTE data session and IP address has been obtained. `False` otherwise. -#### lte.disconnect() +### lte.disconnect() End the data session with the network. -#### lte.send\_at\_cmd(cmd, delay=10000) +### lte.send_at_cmd(cmd, [delay=10000]) -Send an AT command directly to the modem. Returns the raw response from the modem as a string object. **IMPORTANT:** If a data session is active (i.e. the modem is _connected_), sending the AT commands requires to pause and then resume the data session. This is all done automatically, but makes the whole request take around 2.5 seconds. +Send an AT command directly to the modem. Returns the raw response from the modem as a string object. You can find the possible AT commands [here](/gitbook/assets/Monarch-LR5110-ATCmdRefMan-rev6_noConfidential.pdf). + +>If a data session is active (i.e. the modem is _connected_), you will need to `lte.pppsuspend()` and `lte.pppresume` around the AT command. 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 +* `delay` : specify the number of milliseconds the esp32 chip will wait between sending an AT command to the modem. and reading the response. -def send_at_cmd_pretty(cmd): - response = lte.send_at_cmd(cmd).split('\r\n') - for line in response: - print(line) - -send_at_cmd_pretty('AT!="showphy"') # get the PHY status -send_at_cmd_pretty('AT!="fsm"') # get the System FSM -``` - -- `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() +### lte.imei() Returns a string object with the IMEI number of the LTE modem. -#### lte.iccid() +### lte.iccid() Returns a string object with the ICCID number of the SIM card. -#### lte.reset() +### lte.reset() Perform a hardware reset on the cellular modem. This function can take up to 5 seconds to return as it waits for the modem to shutdown and reboot. -#### lte.pppsuspend() +### lte.pppsuspend() Suspend PPP session with LTE modem. this function can be used when needing to send AT commands which is not supported in PPP mode. -#### lte.pppresume() +### lte.pppresume() Resumes PPP session with LTE modem. -#### lte.factory\_reset() +### lte.factory_reset() Reset modem configuration to Factory settings. -#### lte.modem\_upgrade\_mode() +### 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. +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. - --- +> In this mode all All tasks on the board are halted and a reset is required to regain functionality. -#### lte.reconnect\_uart() +### lte.reconnect_uart() Reconnect esp32 UART 2 to LTE modem UART port. -#### lte.ue\_coverage() +### lte.ue_coverage() -Check Network Coverage for UE device (i.e LTE modem). +Check Network Coverage for UE device (i.e LTE modem). Returns: -`True`: There is Network Coverage. - -`False`: No Netwok Coverage. +* `True`: There is Network Coverage. +* `False`: No Netwok Coverage. ## Constants -- `LTE.IP` : Internet Protocol IP +* `LTE.IP` : Internet Protocol IP -- `LTE.IPV4V6` : Internet protocol ver. 4/6 +* `LTE.IPV4V6` : Internet protocol ver. 4/6 + +* `PSM_PERIOD_2S`, `PSM_PERIOD_30S`, `PSM_PERIOD_1M`, `PSM_PERIOD_10M`, `PSM_PERIOD_1H`, `PSM_PERIOD_10H`, `PSM_PERIOD_320H`: Specify the unit for the PSM period to be 2 seconds, 30 seconds, 1 minute, 10 minutes, 1 hour, 10 hours, or 320 hours, respectively. +* `PSM_PERIOD_DISABLED`: Means turning PSM off. +* `PSM_ACTIVE_2S`, `PSM_ACTIVE_1M`, `PSM_ACTIVE_6M`: Specify the unit for the PSM active duration to be 2 seconds, 1 minute, or 6 minutes, respectively. +* `PSM_ACTIVE_DISABLED`: Means turning PSM off. diff --git a/content/firmwareapi/pycom/network/wlan.md b/content/firmwareapi/pycom/network/wlan.md index c831ac2..e6eda98 100644 --- a/content/firmwareapi/pycom/network/wlan.md +++ b/content/firmwareapi/pycom/network/wlan.md @@ -39,72 +39,61 @@ 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 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. -{{% /hint %}} +> The WLAN constructor is special in the sense that if no arguments 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. ## 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=WLAN.INT_ANT, power_save=False, hidden=False, bandwidth=HT40, max_tx_pwr=20, country=NA, protocol=(1,1,1)]) Set or get the WiFi network processor configuration. Arguments are: -* `mode` can be either `WLAN.STA`, `WLAN.AP`, or `WLAN.STA_AP`. -* `ssid` is a string with the SSID name. Only needed when mode is `WLAN.AP`. -* `auth` is a tuple with (sec, key). Security can be `None`, `WLAN.WEP`, `WLAN.WPA`, or `WLAN.WPA2`. The key is a string with the network password. - * If `sec` is `WLAN.WEP` the key must be a string representing hexadecimal values (e.g. `ABC1DE45BF`). Only needed when mode is `WLAN.AP`. -* `channel` a number in the range 1-11. Only needed when mode is `WLAN.AP`. -* `antenna` selects between the internal and the external antenna. Can be either `WLAN.INT_ANT`, `WLAN.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. - -* `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 +* `mode`: can be either: + * `WLAN.STA`: Station mode, connect to a WiFinetwork + * `WLAN.AP`: Access Point mode, create a WiFi network. You _must_ specify the `ssid` + * `WLAN.STA_AP`: Both Station and Access Point mode are active. +* `ssid`: a string with the SSID name. +* `auth`: a tuple with `(sec, key)`. Security can be one of the following. The key is a string with the network password. + * `None`: + * `WLAN.WEP`: Using this in `WLAN.AP`, the key must be a string of hexadecimal values. + * `WLAN.WPA` + * `WLAN.WPA2` + * `WLAN.WPA2_ENT`: this will use the following format: `(sec, username, password)` +* `channel`: a number in the range 1-11. Only needed when mode is `WLAN.AP`. +* `antenna`: select between the internal and the external antenna. With our development boards it defaults to using the on-board antenna. Value can be either: + * `WLAN.INT_ANT` + * `WLAN.EXT_ANT` +* `power_save` enables or disables power save functions in `WLAN.STA` mode. +* `hidden`: create a hidden SSID when set to `True`. only valid in `WLAN.AP` mode. +* `bandwidth` is the Bandwidth to use, either: + * `WLAN.HT20`: 20MHz + * `WLAN.HT40`: 40MHz +* `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 +* `protocol` tuple representing the protocol. see `WLAN.wifi_protocol()` 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) -``` - -or - -```python -# configure as an station -wlan.init(mode=WLAN.STA) -``` - -{{% 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, hostname=None]) -Connect to a wifi access point using the given SSID, and other security parameters. +Connect to a WiFi Access Point using the given SSID, and other parameters -* `auth` is a tuple with `(sec, key)`. Security can be `None`, `WLAN.WEP`, `WLAN.WPA`, `WLAN.WPA2` or `WLAN.WPA2_ENT`. The key is a string with the network password. - * If `sec` is `WLAN.WEP` the key must be a string representing hexadecimal values (e.g. `ABC1DE45BF`). - * If `sec` is `WLAN.WPA2_ENT` then the `auth` tuple can have either 3 elements: `(sec, username, password)`, or just 1: `(sec,)`. When passing the 3 element tuple, the`keyfile` and `certifle` arguments must not be given. -* `bssid` is the MAC address of the AP to connect to. Useful when there are several APs with the same SSID. +* `ssid`: a string with the SSID name. +* `auth`: a tuple with `(sec, key)`. Security can be one of the following. The key is a string with the network password. + * `None`: + * `WLAN.WEP`: Using this in `WLAN.AP`, the key must be a string of hexadecimal values. + * `WLAN.WPA` + * `WLAN.WPA2` + * `WLAN.WPA2_ENT`: this will use the following format: `(sec, username, password)` +* `bssid` is the MAC address of the AP to connect to. This is useful when there are several APs with the same SSID. * `timeout` is the maximum time in milliseconds to wait for the connection to succeed. * `ca_certs` is the path to the CA certificate. This argument is not mandatory. * `keyfile` is the path to the client key. Only used if `username` and `password` are not part of the `auth` tuple. @@ -112,36 +101,27 @@ Connect to a wifi access point using the given SSID, and other security paramete * `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 %}} +> 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. -#### wlan.scan(\[ssid=NULL, bssid=NULL, channel=0, show\_hidden=False, type=WLAN.SCAN\_ACTIVE, scantime=120ms\]) + +### wlan.scan([ssid=None, bssid=None, channel=0, show_hidden=False, type=WLAN.SCAN_ACTIVE, scantime=120ms]) 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. 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. +* `ssid`: Scan only for the given ssid +* `bssid`: Scan only for the givenbssid. The bssid is given as 6 Hexadecimal bytes literals (i.e `b'\xff\xff\xff\xff\xff\xff'`) +* `channel`: If set to 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan. +* `show_hidden`: Scan for hidden ssid's as well. +* `type`: The type of scan performed. Values can be + * `WLAN.SCAN_ACTIVE`: the scan is will be performed by sending a probe request. + * `WLAN.SCAN_PASSIVE`: switches to a specifi channel and waits for beacon +* `scantime` : This field is used to control how long the scan dwells on each channel. For active scans, dwell times for each channel are listed below. For passive scans, this designates the dwell time for each channel. 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() @@ -151,25 +131,24 @@ Disconnect from the WiFi access point. 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. -With no parameters given returns a 4-tuple of `(ip, subnet_mask, gateway, DNS_server)`. +Get or set the interface configuration. -If `dhcp` is passed as a parameter then the DHCP client is enabled and the IP params are negotiated with the AP. +Optionally specify the configuration parameter: -If the 4-tuple config is given then a static IP is configured. For instance: +* `config='dhcp'`: If 'dhcp' is passed as a parameter, then the DHCP client is enabled and the IP parameters are negotiated with the DHCP server. +* `config=(ip, nm, gw, dns)`: If the 4-tuple config is given then a static IP is configured. -```python -wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8')) -``` +For example: `eth.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). @@ -179,29 +158,26 @@ 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\]) +### wlan.channel([channel, secondary_channel=WLAN.SEC_CHN_NONE]) -_In AP mode:_ +* In AP mode, this will get or set the WiFi channel. The secondary channel has no effect. +* In STA mode, this will get the channel. Setting the channel is only allowed in Promiscuous mode. A secondary channel can be given as well if the bandwidth is set to `WLAN.HT40`, choosing from the following: + * `WLAN.SEC_CHN_POS_ABOVE`: Choose a secondary channel above the currently selected channel + * `WLAN.SEC_CHN_POS_BELOW`: Choose a secondary channel below the currently selected channel + * `WLAN.SEC_CHN_NONE` +Possible channels are in the range of 1-14, depending on your country settings. -Get or set the wifi channel +### wlan.antenna([antenna]) -_In STA mode:_ +Get or set the antenna type (external or internal). Value can be: -`channel`: is the primary channel to listen to. -_Note: Setting Channel in STA mode is only Allowed in Promiscuous mode_ - -### wlan.antenna(\[antenna\]) - -Get or set the antenna type (external or internal). - -### wlan.mac(\[mac, mode\]) +### 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 @@ -219,21 +195,28 @@ _Note: STA and AP cannot have the Same Mac Address_ ### wlan.bandwidth() -Set the bandwidth of the wifi, either 20 MHz or 40 MHz can be configured, use constants `HT20` or `HT40` +Set the bandwidth of the wifi, either 20 MHz or 40 MHz can be configured, use the following: +* `WLAN.HT20`: 20MHz +* `WLAN.HT40`: 40MHz ### 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() +### 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\]). +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\]) +### wlan.ap_tcpip_sta_list() + +This API returns with a list of the devices connected to the Pycom board when it is in AP mode. +Each element of the returned list is a tuple, containing the MAC address and IP address of the device. + +### wlan.max_tx_power([power]) Gets or Sets the maximum allowable transmission power for wifi. @@ -241,38 +224,41 @@ Packets of different rates are transmitted in different powers according to the 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 +* [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\]) +### wlan.country([country, schan, nchan, max_tx_pwr, policy]) -Gets or set s Country configuration parameters for wifi. +Gets or sets 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. +* `policy` Is the method when setting country configuration. Possible options are + * `WLAN.COUNTRY_POL_AUTO` in STA mode the wifi will aquire the same country config of the connected AP + * `WLAN.COUNTRY_POL_MAN` the configured country parameters will take effect regardless of connected AP. -### wlan.joined\_ap\_info() +### 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. +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)\]) +### 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) +Sets or gets Wifi Protocol supported. Sets or gets Wifi Protocol supported in (`PHY_11_B`,`PHY_11_G`,`PHY_11_N`) format. Currently 802.11b or 802.11bg or 802.11bgn mode is available. + +### wlan.send_raw(Buffer, interface=STA, use_sys_seq=True) Send raw data through the Wifi Interface. @@ -282,16 +268,23 @@ Send raw data through the Wifi Interface. `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) +### 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. +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. Possible triggers: -For trigger events see `Constants` section. +* `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. +* `WLAN.SMART_CONF_DONE`: Smart Config of wifi ssid/pwd Finished +* `WLAN.SMART_CONF_TIEMOUT`: Smart Config of wifi ssid/pwd timed-out -### wlan.promiscuous(\[bool\]) +### 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 +Gets or sets WiFi Promiscuous mode. Note: @@ -325,29 +318,41 @@ wlan.promiscuous(True) This function will return an integer object as mask for triggered events. -### wlan.wifi\_packet() +### wlan.wifi_packet() This function will return a tuble with Wifi packet info captured in promiscuous mode. -### wlan.ctrl\_pkt\_filter(\[int\]) +### wlan.ctrl_pkt_filter([int]) + +This function is used to set the filter mask for Wifi control packets in promiscuous mode. Possible filters: + +* `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 -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. -### wlan.smartConfig\(\) +### wlan.smartConfig() Start SmartConfig operation, the smartConfig is a provisioning technique that enables setting Wifi credentials for station mode wirelessly via mobile app. -####Steps: -- call **wlan.smartConfig()** \(if smartConfig is not enabled on boot or you want to restart smartConfig\) +#### Steps: +- call `wlan.smartConfig()` (if smartConfig is not enabled on boot or you want to restart smartConfig) - Use mobile App (ESP touch or Pycom App) to set ssid and password for the AP -- You can register a callback to be triggered when smart Config is Finesed successfuly or timedout. +- You can register a callback to be triggered when smart Config is Finished successfuly or times out. -### wlan.Connected\_ap\_pwd() +### wlan.Connected_ap_pwd() Get the password of AP the Device is connected to. + ## Constants * WLAN mode: `WLAN.STA`, `WLAN.AP`, `WLAN.STA_AP` @@ -357,43 +362,6 @@ Get the password of AP the Device is connected to. * 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. - - `SMART_CONF_DONE`: Smart Config of wifi ssid/pwd Finished - - `SMART_CONF_TIEMOUT`: Smart Config of wifi ssid/pwd timed-out - -* 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 +* Secondary Channel position: `WLAN.SEC_CHN_POS_ABOVE`, `WLAN.SEC_CHN_POS_BELOW`, `WLAN.SEC_CHN_NONE` +* Wlan callback triggers: `WLAN.EVENT_PKT_MGMT`, `WLAN.EVENT_PKT_CTRL`, `WLAN.EVENT_PKT_DATA`, `WLAN.EVENT_PKT_DATA_MPDU`, `WLAN.EVENT_PKT_DATA_AMPDU`, `WLAN.EVENT_PKT_MISC`, `WLAN.EVENT_PKT_ANY`, `SMART_CONF_DONE`, `SMART_CONF_TIEMOUT` +* Control packet filters in promiscuous mode: `WLAN.FILTER_CTRL_PKT_ALL`, `WLAN.FILTER_CTRL_PKT_WRAPPER`, `WLAN.FILTER_CTRL_PKT_BAR`, `WLAN.FILTER_CTRL_PKT_BA`, `WLAN.FILTER_CTRL_PKT_PSPOLL`, `WLAN.FILTER_CTRL_PKT_CTS`, `WLAN.FILTER_CTRL_PKT_ACK`, `WLAN.FILTER_CTRL_PKT_CFEND`, `WLAN.FILTER_CTRL_PKT_CFENDACK` diff --git a/content/firmwareapi/pycom/pycom.md b/content/firmwareapi/pycom/pycom.md index 667052b..ba929cd 100644 --- a/content/firmwareapi/pycom/pycom.md +++ b/content/firmwareapi/pycom/pycom.md @@ -19,119 +19,37 @@ pycom.heartbeat() # get the heartbeat state pycom.rgbled(0xff00) # make the LED light up in green color ``` -## Methods +## Miscelaneous Methods -#### pycom.heartbeat\(\[boolean\]\) +### pycom.heartbeat([boolean]) -Get or set the state (enabled or disabled) of the heartbeat LED. Accepts and returns boolean values (`True` or `False`). +Get or set the state (enabled or disabled) of the heartbeat LED. Accepts and returns boolean values. -#### pycom.heartbeat\_on\_boot\(\[boolean\]\) +### pycom.rgbled(color) -Allows you permanently disable or enable the heartbeat LED. Once this setting is set, it will persist between reboots. Note, this only comes into effect on the next boot, it does not stop the already running heartbeat. +Set the colour of the RGB LED. The colour is specified as 24 bit value representing red, green and blue, in the following order `0xRRGGBB`. For instance, passing the value `0x00FF00` will light up the LED in a very bright green. -#### pycom.rgbled(color) - -Set the colour of the RGB LED. The colour is specified as 24 bit value representing red, green and blue, where the red colour is represented by the 8 most significant bits. For instance, passing the value `0x00FF00` will light up the LED in a very bright green. - -#### pycom.nvs\_set(key, value) +### pycom.nvs_set(key, value) 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) -pycom.nvs_set('count', 10) -``` - -#### pycom.nvs\_get(key) +### pycom.nvs_get(key) Get the value the specified key from the NVRAM memory area of the external flash. Example: -```python -import pycom - -pulses = pycom.nvs_get('count') -``` - If a non-existing key is given the returned value will be `None`. -#### pycom.nvs\_erase(key) +### pycom.nvs_erase(key) Erase the given key from the NVRAM memory area. -#### pycom.nvs\_erase\_all() +### pycom.nvs_erase_all() Erase the entire NVRAM memory area. -#### pycom.wifi\_on\_boot\(\[boolean\]\) +### pycom.pulses_get(pin, timeout) -Get or set the WiFi on boot flag. When this flag is set to `True`, The Wifi will be enabled according to the other wifi settings eg (ssid\_sta, pwd\_sta, ssid\_ap, pwd\_ap). when `False` the Wifi module will be disabled untill enabled directly via 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 -pycom.wifi_on_boot() # get the wifi on boot flag -``` - -#### pycom.wifi\_ssid\_sta\([ssid]\) - -Get or set the ssid of the Access point the device should connect to on startup. -This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.wifi\_ssid\_ap\([ssid]\) - -Get or set the ssid of the Access point that should be started by the device at startup, if not set and startup Wifi mode is AP the default AP name \(\-wlan-\\) will be used.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.wifi\_pwd\_sta\([key]\) - -Get or set the Password of the Access point the device should connect to on startup, leave the password unset if the AP is open.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.wifi\_pwd\_ap\([key]\) - -Get or set the Password of the Access point that should be started by the device at startup, leave unset if the AP should be open.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.smart\_config\_on\_boot\([boolean]\) - -Read or (Enable/Disable) SmartConfig functionality on startup, this flag will be reset after successful completion of the smartConfig process after startup.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.smart\_config\_on\_boot\([boolean]\) - -Read or (Enable/Disable) SmartConfig functionality on startup, this flag will be reset after successful completion of the smartConfig process after startup.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.wifi\_mode\_on\_boot\(\[boolean\]\) - -Set or get the Wifi Mode at startup , `WLAN.STA`, `WLAN.AP` or `WLAN.APSTA`.This setting is stored in non-volatile memory which preserves it across resets and power cycles - -#### pycom.wdt\_on\_boot\_timeout(\[timeout\]) - -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 -pycom.wdt_on_boot_timeout() # get the WDT timeout value -``` - -#### pycom.wdt\_on\_boot\(\[enable\]\) - -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 -pycom.wdt_on_boot() # get the WDT on boot flag -``` - -#### pycom.pulses\_get\(pin, timeout\) - -Return a list of pulses at `pin`. The methods scans for transitions at `pin` and returns a list of tuples, each telling the pin value and the duration in microseconds of that value. `pin` is a pin object, which must have set to `INP` or `OPEN_DRAIN` mode. The scan stops if not transitions occurs within `timeout` milliseconds. +Return a list of pulses at `pin`. The methods scans for transitions at `pin` and returns a list of tuples, each telling the pin value and the duration in microseconds of that value. `pin` is a pin object, which must have set to `INP` or `OPEN_DRAIN` mode. The scan stops if no transitions occur within `timeout` milliseconds. Example: @@ -147,12 +65,98 @@ sleep_ms(20) pin(1) data = pulses_get(pin, 100) ``` +### pycom.get_free_heap() -#### pycom.ota\_start() +Returns the free heap bytes in the memory allocation -#### pycom.ota\_write(buffer) +### pycom.sigfox_info([id, pac, publickey, privatekey]) -#### pycom.ota\_finish() +With no arguments, this function will return if the SigFox settings on the device are valid. + +With arguments, the specified keys will be set. + + +## Boot methods + +### pycom.pybytes_on_boot() + +Get or set the activation of pybytes on boot. + +### pycom.heartbeat_on_boot([boolean]) + +Allows you permanently disable or enable the heartbeat LED. Once this setting is set, it will persist between reboots. Note, this only comes into effect on the next boot, it does not stop the already running heartbeat. + +### pycom.lte_modem_on_boot([boolean]) + +Get or set the LTE modem on boot flag. When this flag is set to `True`, the LTE modem will be enabled. +### pycom.wifi_on_boot([boolean]) + +Get or set the WiFi on boot flag. When this flag is set to `True`, The WiFi will be enabled according to the other WiFi settings. when `False` the WiFi module will be disabled untill enabled directly via WLAN class. + +This setting is stored in non-volatile memory which preserves it across resets and power cycles. + +### pycom.wifi_ssid_sta([ssid]) + +Get or set the ssid of the Access Point the device should connect to on startup. +This setting is stored in non-volatile memory which preserves it across resets and power cycles + +### pycom.wifi_ssid_ap([ssid]) + +Get or set the ssid of the Access point that should be started by the device at startup, if not set and startup Wifi mode is AP the default AP name (`Board_Name>-wlan- 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. + +## OTA Methods + +### pycom.ota_start() + +### pycom.ota_write(buffer) + +### pycom.ota_finish() + +### pycom.ota_slot() + +### pycom.ota_verify() Perform a firmware update. These methods are internally used by a firmware update through FTP. The update starts with a call to `ota_start()`, followed by a series of calls to `ota_write(buffer)`, and is terminated with `ota_finish()`. After reset, the new image gets active. `buffer` shall hold the image data to be written, in arbitrary sizes. A block size of 4096 is recommended. @@ -189,19 +193,13 @@ 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. - -#### pycom.diff_update_enabled() +> For more information about the OTA process, go [here](/updatefirmware/ota/) +### pycom.diff_update_enabled() Provides the status of the differential update feature. Returns `True` if differential update is enabled and `False` otherwise. `DIFF_UPDATE_ENABLED` build flag can be used to enable the differential update feature. > Note: This function is only available in the firmware versions which support differential update feature. If you get an exception while calling this function, your firmware version does not support this feature. +## Constants + +`pycom.LittleFS`, `pycom.FAT`, `pycom.FACTORY`, `pycom.OTA_0` diff --git a/content/gettingstarted/_index.md b/content/gettingstarted/_index.md index 8f3657c..1953569 100644 --- a/content/gettingstarted/_index.md +++ b/content/gettingstarted/_index.md @@ -30,7 +30,7 @@ This step works the same for all our development boards and expansion boards. In ![](/gitbook/assets/expansion_board_3_lopy4.png) ->Note: If you do not have an expansion board, you are able to use a [USB-Serial converter](/gettinstarted/programming/usbserial/) or [WiFi](/gettingstarted/programming/ftp/) to connect. +>Note: If you do not have an expansion board, you are able to use a [USB-Serial converter](/gettingstarted/programming/usbserial/) or [WiFi](/gettingstarted/programming/ftp/) to connect. ## Step 2: Setting up your computer @@ -130,11 +130,11 @@ If you need to remove files from your device you can use the following commands: ## Step 4: Further references Now that we got the basic example running, you can proceed to develop your own application! For further references, you can check the links below: -* [More examples](/tutorials/) +* [Tutorials and examples](/tutorials/) -* [Documentation](/firmwareapi/) +* [Firmware API](/firmwareapi/) -* [Get started using the FTP and Telnet Server](/gettingstarted/programming/ftp/) +* [FTP and Telnet](/gettingstarted/programming/ftp/) * [Connect using Pybytes](/pybytes/getstarted/) diff --git a/content/gettingstarted/programming/safeboot.md b/content/gettingstarted/programming/safeboot.md index 9195ce3..9bd4f84 100644 --- a/content/gettingstarted/programming/safeboot.md +++ b/content/gettingstarted/programming/safeboot.md @@ -30,7 +30,7 @@ If problems occur within the filesystem or you wish to factory reset your module ```python >>> import os ->>> os.fsformat('flash') +>>> os.fsformat('/flash') ``` > Be aware, formatting the flash filesystem will delete all files inside the internal device storage (not the SD card) and they cannot be recovered. diff --git a/content/gettingstarted/registration/_index.md b/content/gettingstarted/registration/_index.md index bcc3e06..7348163 100644 --- a/content/gettingstarted/registration/_index.md +++ b/content/gettingstarted/registration/_index.md @@ -10,7 +10,7 @@ Some of our devices require registration before you can utilise specific feature * [Objenious](/gettingstarted/registration/lora/objenious/) ## Other * [SigFox](/gettingstarted/registration/sigfox/) -* [Cellular](/gettinsgtarted/registration/cellular/) +* [Cellular](/gettingstarted/registration/cellular/) >**Not all Pycom devices require activation**; most features work immediately out of the box! diff --git a/content/gettingstarted/registration/lora/_index.md b/content/gettingstarted/registration/lora/_index.md index a8138a0..cec77eb 100644 --- a/content/gettingstarted/registration/lora/_index.md +++ b/content/gettingstarted/registration/lora/_index.md @@ -27,11 +27,11 @@ 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/networks/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/networks/lora/lorawan-abp) code to connect to the network. ### Networks diff --git a/content/gettingstarted/registration/lora/ttn.md b/content/gettingstarted/registration/lora/ttn.md index ab6f8d9..de169d4 100644 --- a/content/gettingstarted/registration/lora/ttn.md +++ b/content/gettingstarted/registration/lora/ttn.md @@ -45,7 +45,7 @@ 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/networks/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. diff --git a/content/pybytes/_index.md b/content/pybytes/_index.md index 6b3fe10..75d15be 100644 --- a/content/pybytes/_index.md +++ b/content/pybytes/_index.md @@ -26,10 +26,13 @@ In a nutshell, Pybytes is an environment designed to optimise your IoT applicati * Firmware updates over the air: Upgrade or downgrade firmware versions with our exclusive firmware update. * Track your assets position: Google Maps API means you can track your device's geolocation. +> Note: If the [Pybytes website](https://pybytes.pycom.io/) seems to be down for you, do not worry! + > * In Chrome, open developer settings using F12, click on the `Application` tab and `Service workers` next to the gear icon. Then, open the menu `service workers from other origins` and click `unregister`. That should solve the problem! + ## Let's get started! -* [Getting started with Pybytes](/pybytes/getstarted) -* [Connect your Pycom module to Pybytes](/pybytes/connect) -* [Visualise data from your device](/pybytes/dashboard) -* [LoRa Servers](/pybytes/lora) +* [Getting started with Pybytes](/pybytes/getstarted/) +* [Connect your Pycom module to Pybytes](/pybytes/connect/) +* [Visualise data from your device](/pybytes/dashboard/) +* [LoRa Servers](/pybytes/networks/lora/) * ​[Integrations with external services](/pybytes/integrations/index.html)​ diff --git a/content/pybytes/api/_index.md b/content/pybytes/api/_index.md index 55d2510..d373e84 100644 --- a/content/pybytes/api/_index.md +++ b/content/pybytes/api/_index.md @@ -30,7 +30,7 @@ There are multiple debug levels, the lowest is 0 which is for warnings only and * [Activate](activate) -* [Connect](connect) +* [Connect](connect_device) * [Connect LTE](connect_lte) diff --git a/content/pybytes/dashboard.md b/content/pybytes/dashboard.md index dc80039..86a39c8 100644 --- a/content/pybytes/dashboard.md +++ b/content/pybytes/dashboard.md @@ -18,7 +18,7 @@ The first step is to have your python application uploaded and running on your P 1. Install the [Pymakr](https://atom.io/packages/pymakr) plugin. - (We highly recommend using Pymakr with Atom, but you can also use Pymakr with [VS Code](https://marketplace.visualstudio.com/items?itemName=pycom.Pymakr)). Learn more about Pymakr [here](/pymakr). + (We highly recommend using Pymakr with Atom, but you can also use Pymakr with [VS Code](https://marketplace.visualstudio.com/items?itemName=pycom.Pymakr)). 2. In Atom create a project folder `my-first-wipy` (any other name will work as well). 4. In your project folder create the `main.py` file 3. Copy and paste the following code into your `main.py` diff --git a/content/pybytes/mlintegration/_index.md b/content/pybytes/mlintegration/_index.md new file mode 100644 index 0000000..becbf89 --- /dev/null +++ b/content/pybytes/mlintegration/_index.md @@ -0,0 +1,18 @@ +--- +title: "Machine Learning Integration" +aliases: +--- + +## What does Machine Learning integration offer you? + +This documentation is a quick introduction to the new Machine Learning integration features on Pybytes. + +The Machine Learning integration is here to help you to create smart machine learning models using Pycom devices. + +## Let's get started! + +* [Device Settings](/pybytes/mlintegration/devicesettings) + +* [Machine Learning Model Creation](/pybytes/mlintegration/modelcreation) + +* [Machine Learning Features](/pybytes/mlintegration/features) diff --git a/content/pybytes/mlintegration/devicesettings.md b/content/pybytes/mlintegration/devicesettings.md new file mode 100644 index 0000000..7204094 --- /dev/null +++ b/content/pybytes/mlintegration/devicesettings.md @@ -0,0 +1,12 @@ +## Device Settings + +### What do you need for the machine learning data acquisition and testing: + +To make the data acquisition you need a Pycom device + a Pysense or a Pytrack. + +You also need to update the device firmware to the latest version - v1.20.2.r1 + +The Pysense and Pytrack require libraries, please upload the **pycoproc.py**, **LIS2HH12.py** to the device repository **lib/**. In case of Pysense upload the **pysense.py** in case of Pytrack upload **pytrack.py**. +Those libraries can be find in [**Pycom Libraries**](https://github.com/pycom/pycom-libraries). + +Check this link to learn how to create the machine learning model in Pybytes [**Model features**](/pybytes/mlintegration/modelcreation) diff --git a/content/pybytes/mlintegration/features.md b/content/pybytes/mlintegration/features.md new file mode 100644 index 0000000..c0049db --- /dev/null +++ b/content/pybytes/mlintegration/features.md @@ -0,0 +1,98 @@ +## Model Features + +### Data Acquisition + +#### Create Sample + +In the data acquisition module the samples for training can be collected. + +After setting all sample parameters in the form click on **Create Sample** to start. + +The sampling occurs when the device led is amber, when the light turns purple, the device is processing and saving the samples. + +If the device gets stuck showing the purple light, maybe the sampling should be done again. + +#### Data Collection + +The data collection shows the collected samples. Click on the sample to see the graph. + +* Is recommended to have the same number of samples per label. If you have collected 2 samplings for a waving movement, you should have the same number of sampling for the other movements (labels) as well. + +![Data Acquisition](/gitbook/assets/pybytes/ml/data_acquisition_graph.png) + +### Signal Processing + +Signal processing is used to extract features for the Neural Network module. + +There are many ways to extract features. The simplest way is using convolutional layers, but doing this there is no control of what features will be used and also the convolutional layers make the neural network bigger, so more data is needed for training. + +Signal processing provides an easy and intuitively way to extract features and also the features can be analyzed using different methods. + +The input data consists from accelerations values on three axes (X, Y, Z). To analyze the data, a window of a certain size is moved over the data using a moving step. The Window Size and Window Step are model specific and they are defined in the Model Configuration tab. This window is received by the signal processing block as input. + +##### Standardization + +First, the window data can be standardized by subtracting the average and dividing it by its standard deviation, thus obtaining a window with zero mean and a variance equal to one. + +##### Filter + +After the window is standardized, a filter can be applied to the data. The type of the filter (none, low-pass, high-pass), the cutoff frequency and the filter order can be selected by the user. + +##### Features + +Using Fourier analysis (FFT transform), features are extracted from the data. + +Features are calculated for every axis (X, Y, Z), independently of other axes. The next features are available to be selected/used by the user: + +- The root mean square. It is the square root of the arithmetic mean of the squares of the values. +- FFT peaks. First peaks from FFT values, to be used as features. +- Spectral Power on intervals. Mean of the squares of the FFT values, on specified frequencies intervals. + +##### Select Features + +To select the desired features and also to see the filtered data and calculated FFTs, select the data window to be analyzed, fill in the form and click the **Process Signal** button. + +![Processing](/gitbook/assets/pybytes/ml/processing.png) + +#### Training + +The neural network receives its input from the Signal Processing block. + +The number of layers and the number of neurons in this layer can be selected by the user. For the moment there are supported only dense layers as hidden layers. Other parameters that can be selected are: the number of training epochs, the learning rate and the confidence threshold. + +To train the model, fill the Neural Network Settings form and click on **START TRAINING** button. + +The results can be checked on the Training Performance section. + +![Training](/gitbook/assets/pybytes/ml/training.png) + +#### Testing + +In the module, the samples for testing can be collected. + +After setting all sample parameters in the form click on **Create Sample** to start. + +#### Data Collection + +The data collection shows the testing collected samples. Click on the **Test xxx Samples** to test the module. + +![Testing](/gitbook/assets/pybytes/ml/testing.png) + +After the testing is performed, the results can be checked below the Data collection form. + +![Testing Results](/gitbook/assets/pybytes/ml/testing_results.png) + +#### Model Deployment + +After all training and testing, the model can be deployed into the devices. + +Select the devices and click on the **DEPLOY MODEL** button. + +![Model Deployment](/gitbook/assets/pybytes/ml/deploy.png) + +* Once you have the model deployed on the devices, it can be used for furthers applications like movement detection and so on. + +* This file is going to be used by the device firmware, and once generated it should not be changed by the user. Any changes can cause features to malfunction. + + +[**Machine Learning Integration**](/pybytes/mlintegration) diff --git a/content/pybytes/mlintegration/modelcreation.md b/content/pybytes/mlintegration/modelcreation.md new file mode 100644 index 0000000..060849b --- /dev/null +++ b/content/pybytes/mlintegration/modelcreation.md @@ -0,0 +1,42 @@ +## Model Creation + +The first step to use the machine learning feature on Pybytes is the model creation. + +The Machine Learning app can be accessed in the main sidebar. + +![Machine Learning App](/gitbook/assets/pybytes/ml/pybytes_front_page.png) + + +To create a new model, click on **ADD MODEL** button and follow the wizard. + +The existing models are listed below. + +![Create Model](/gitbook/assets/pybytes/ml/ml_page.png) + +### Model Wizard + +#### The first step is the model definition. + +In the model definition the fields **Name**, **Description**, and **Sample frequency** should be fulfilled. + +![Model Definition](/gitbook/assets/pybytes/ml/model_definition.png) + +#### The second step is the model configuration. + +In the model configuration, the processing block type and learning block technique should be selected. + +In the beta version, only the Spectral Analysis (processing block type) and Neural Network (learning block technique) are available. + +![Model Configuration](/gitbook/assets/pybytes/ml/model_config.png) + +#### The third step is the Device Selection. + +In the third step the devices that will be used to train and test the model should be selected. + +![Device Selection](/gitbook/assets/pybytes/ml/select_device.png) + +And now the model is ready to be used! + +![Device Selection](/gitbook/assets/pybytes/ml/model_created.png) + +Check this link to learn how to train and test the model [**Model features**](/pybytes/mlintegration/features) diff --git a/content/pybytes/networks/sigfox/devkit.md b/content/pybytes/networks/sigfox/devkit.md index eb8d356..e48c957 100644 --- a/content/pybytes/networks/sigfox/devkit.md +++ b/content/pybytes/networks/sigfox/devkit.md @@ -47,4 +47,4 @@ This is not an issue with Custom contract, where _device type_ on Sigfox backend ## Troubleshooting -[Disengage Sigfox sequence number](/tutorials/sigfox#disengage-sequence-number) +[Disengage Sigfox sequence number](/tutorials/networks/sigfox#disengage-sequence-number) diff --git a/content/pymesh/pymesh-br.md b/content/pymesh/pymesh-br.md index 202153f..ed9f9b8 100644 --- a/content/pymesh/pymesh-br.md +++ b/content/pymesh/pymesh-br.md @@ -21,7 +21,7 @@ Several things must be accomplished: ## Border Router using CLI -As explained in [Pymesh CLI - Border Router section](pymesh/lib-cli/#border-router-specific), using commands `br` and `brs`, a simple test scenario can be easily implemented. +As explained in [Pymesh CLI - Border Router section](/pymesh/lib-cli/#border-router-specific), using commands `br` and `brs`, a simple test scenario can be easily implemented. ## Border Router using Pymesh API diff --git a/content/pymesh/security.md b/content/pymesh/security.md index 1e4113a..532ebb4 100644 --- a/content/pymesh/security.md +++ b/content/pymesh/security.md @@ -30,10 +30,10 @@ The challenge is in distributing the keys used for encryption(decryption), this Symmetric-key algorithms are algorithms for cryptography that use the same cryptographic keys for both encryption of plaintext and decryption of ciphertext. More info could be checked on [Symmetric-key algorithm](https://en.wikipedia.org/wiki/Symmetric-key_algorithm). -A micropython example script can be seen [here](../../firmwareapi/pycom/aes.md) using AES 128, 192 or 256 bits keys (`crypto.AES` class). +A micropython example script can be seen [here](../../firmwareapi/pycom/aes/) using AES 128, 192 or 256 bits keys (`crypto.AES` class). ### Asymmetric encryption Public-key cryptography, or asymmetric cryptography, is a cryptographic system that uses pairs of keys: public keys which may be disseminated widely, and private keys which are known only to the owner. More info could be checked on [Public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography). -A micropython example script can be seen [here](../../firmwareapi/micropython/ucrypto.md) using RSA 2048 bits keys (`crypto.rsa_encrypt()` method). +A micropython example script can be seen [here](../../firmwareapi/micropython/ucrypto/) using RSA 2048 bits keys (`crypto.rsa_encrypt()` method). diff --git a/content/tutorials/basic/sleep.md b/content/tutorials/basic/sleep.md index 15130e3..5c541b2 100644 --- a/content/tutorials/basic/sleep.md +++ b/content/tutorials/basic/sleep.md @@ -42,7 +42,7 @@ print("this will be printed after 10 seconds: " str(time.ticks_ms())) #### Deep sleep Deepsleep disables, next to the lightsleep, the main CPU and RAM. This leaves only a low power coprocessor and RTC timer running. After waking up, the board will start again at `boot.py`, just like with pressing the reset button. The CPU counter (`time.ticks()`) will continue to count however! -You can also leave the brackets empty to sleep indefinetely, until the reset button is pressed, the power is removed, or an external wake up signal (interrupt) is provided. Be aware that the LTE modem. *** +You can also leave the brackets empty to sleep indefinetely, until the reset button is pressed, the power is removed, or an external wake up signal (interrupt) is provided. Be aware that the LTE modem will remain switched on unless you actively switch off its power, or use its own power saving modes. ```python @@ -82,4 +82,4 @@ print("This will never be printed") >Note: Using `deepsleep()` will also stop the USB connection. Be wary of that when trying to upload new code to the device! -For the Pysense, Pytrack and Pyscan expansionboards, an additional sleep function is available. You can find out more about that [here](../expansionboards/sleep/) \ No newline at end of file +For the Pysense, Pytrack and Pyscan expansionboards, an additional sleep function is available. You can find out more about that [here](/tutorials/expansionboards/sleep/) \ No newline at end of file diff --git a/content/tutorials/expansionboards/pygate.md b/content/tutorials/expansionboards/pygate.md index ec9e5b2..bb58a26 100644 --- a/content/tutorials/expansionboards/pygate.md +++ b/content/tutorials/expansionboards/pygate.md @@ -8,7 +8,7 @@ While the Pygate shield has the radio chips required to act as a LoRaWAN gateway A USB connection is recommended for the initial firmware update of the Pycom development module (WiPy 3, GPy, LoPy4) and to upload the configuration & start-up script. The module can be updated over the air via WiFi / LTE-M (depending on network capabilities) or via Ethernet connection which allows installation of the gateway in remote locations. -The Pygate board can have the PyEthernet adapter connected which allows an Ethernet connection. The PyEthernet also supports PoE. Please check the separate [page and warning for PoE-NI!](/tutorials/all/poe) +The Pygate board can have the PyEthernet adapter connected which allows an Ethernet connection. The PyEthernet also supports PoE. Please check the separate [page and warning for PoE-NI!](/tutorials/networkprotocols/poe/) ### Quickstart diff --git a/content/tutorials/introduction.md b/content/tutorials/introduction.md index aaaaacc..9586af0 100644 --- a/content/tutorials/introduction.md +++ b/content/tutorials/introduction.md @@ -14,7 +14,7 @@ This section contains tutorials and examples for use with Pycom modules and Expa General Pycom tutorials contains tutorials that may be run on any Pycom device, such as connecting to a WiFi network, Bluetooth, controlling I/O pins etc. Later sections are specific to the LoPy and SiPy devices such as setting up a LoRa node or connecting to the Sigfox network. The final sections are related to examples using the Pytrack and Pysense. -Before starting, ensure that any Pycom devices are running the latest firmware; for instructions see [Firmware Updates](/gettingstarted/installation/firmwaretool). +Before starting, ensure that any Pycom devices are running the latest firmware; for instructions see [Firmware Updates](/updatefirmware/device/). The source code for these tutorials, along with the required libraries can be found in in the [pycom-libraries](https://github.com/pycom/pycom-libraries) repository. diff --git a/content/tutorials/networkprotocols/PoE.md b/content/tutorials/networkprotocols/PoE.md index 32e04a3..3528c33 100644 --- a/content/tutorials/networkprotocols/PoE.md +++ b/content/tutorials/networkprotocols/PoE.md @@ -23,72 +23,32 @@ Incorrect usages of Power over Ethernet can lead to unrecoverable damage of not A battery can be connected to the PyGate without issues. The battery can be charged either via USB-C or PoE power. -

Setup Options

+## Setup Options +In the following diagram, we clarify what is, and what is not allowed: + +### Power over Ethernet + -

Power over Ethernet

![](/gitbook/assets/poe-ni-warn1.png) -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
USB-C cable connected to a PC with mains ground protectionNOT OK
USB-C cable connected to a Notebook without mains ground protection OK
USB-C charger with mains ground protection NOT OK
USB-C charger without mains ground protection OK
Oscilloscope / Logic Analyser / Other equipment with mains ground protection NOT OK
Battery OK
-
+| Connection type | OK?| +|--- |--- | +|USB-C cable connected to a PC with mains ground protection|NOT OK| +|USB-C cable connected to a Notebook without mains ground protection|OK| +|USB-C charger with mains ground protection|NOT OK| +|USB-C charger without mains ground protection|OK| +|Oscilloscope / Logic Analyser / Other equipment with mains ground protection|NOT OK| +|Battery|OK| + +### Power over USB-C / External -

-

Power over USB-C or external supply

![](/gitbook/assets/poe-ni-warn2.png) -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
USB-C cable connected to a PC with mains ground protectionOK
USB-C cable connected to a Notebook without mains ground protection OK
USB-C charger with mains ground protection OK
USB-C charger without mains ground protection OK
Oscilloscope / Logic Analyser / Other equipment with mains ground protection OK
Battery OK
-
+ +| Connection type | OK?| +|--- |--- | +|USB-C cable connected to a PC with mains ground protection| OK| +|USB-C cable connected to a Notebook without mains ground protection|OK| +|USB-C charger with mains ground protection| OK| +|USB-C charger without mains ground protection|OK| +|Oscilloscope / Logic Analyser / Other equipment with mains ground protection| OK| +|Battery|OK| \ No newline at end of file diff --git a/content/tutorials/networkprotocols/blemesh.md b/content/tutorials/networkprotocols/blemesh.md new file mode 100644 index 0000000..31c2a9e --- /dev/null +++ b/content/tutorials/networkprotocols/blemesh.md @@ -0,0 +1,253 @@ +--- +title: "Pymesh BLE Examples" +aliases: + - tutorials/all/ble_mesh.html + - tutorials/all/ble_mesh.md + - chapter/tutorials/all/ble_mesh +--- + +Pymesh BLE module enables many-to-many device connections, based on the Bluetooth module. + +For the API, please check the section [Pymesh BLE API](/firmwareapi/pycom/network/bluetooth/ble_mesh/). + +## Generic OnOff Example +Generic OnOff model is one of the simplest model in BLE Mesh. + +This model illustrates the light-switches (OnOff Client) and light-bulbs (OnOff Server). In other words, the Client can send on/off commands to one/all nodes, and the Server is records state changes based on these commands. + +### OnOff Server + +OnOff Server has one boolean State. Server can Get, Set or send Status about this State to Client(s). + +In the example below, during Provisioning, `Output OOB` can be selected. LED is yellow in case of Not-provisioned, and green in case of Provisioned state. + +Changing the State of Server, LED's light is green or red. + +```python +from network import Bluetooth +import pycom +import time + +BLE_Name = "OnOff Server 18" + +def blink_led(n): + for x in range(n): + pycom.rgbled(0xffff00) # yellow on + time.sleep(0.3) + pycom.rgbled(0x000000) # off + time.sleep(0.3) + +def server_cb(new_state, event, recv_op): + print("SERVER | State: ", new_state) + + # Turn on LED on board based on State + if new_state == True: + pycom.rgbled(0x007f00) # green + else: + pycom.rgbled(0x7f0000) # red + +def prov_callback(event, oob_pass): + if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT): + # Yellow if not Provision yet or Reseted + pycom.rgbled(0x555500) + if(event == BLE_Mesh.PROV_COMPLETE_EVT): + # Green if Provisioned + pycom.rgbled(0x007f00) + if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT): + print("Privisioning blink LED num:", oob_pass) + blink_led(oob_pass) + +# BLE Mesh module +BLE_Mesh = Bluetooth.BLE_Mesh + +# Turn off the heartbeat behavior of the LED +pycom.heartbeat(False) + +# Need to turn ON Bluetooth before using BLE Mesh +bluetooth = Bluetooth() + +# Create a Primary Element with GATT Proxy feature and add a Server model to the Element +element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY) +model_server = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.SERVER, callback=server_cb) + +# Initialize BLE_Mesh +BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback) + +# Turn on Provisioning Advertisement +BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT) + +print("\nBLE Mesh started") +print(BLE_Name, "waits to be provisioned\n") + +""" +# After this node was provisioned +# Current state can be read using +model_server.get_state() +""" +``` + +### OnOff Client + +Client can Get or Set State of Server. In case of Get, or Server Status, Client Gets the Status through the Model's callback. + +```python +from network import Bluetooth +import pycom +import time + +BLE_Name = "OnOff Client 17" + +def blink_led(n): + for x in range(n): + pycom.rgbled(0xffff00) # yellow on + time.sleep(0.3) + pycom.rgbled(0x000000) # off + time.sleep(0.3) + +def client_cb(new_state, event, recv_op): + print("CLIENT | State: ", new_state) + +def prov_callback(event, oob_pass): + if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT): + # Yellow if not Provision yet or Reseted + pycom.rgbled(0x555500) + if(event == BLE_Mesh.PROV_COMPLETE_EVT): + # Green if Provisioned + pycom.rgbled(0x007f00) + if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT): + print("Privisioning blink LED num:", oob_pass) + blink_led(oob_pass) + +# BLE Mesh module +BLE_Mesh = Bluetooth.BLE_Mesh + +# Turn off the heartbeat behavior of the LED +pycom.heartbeat(False) + +# Need to turn ON Bluetooth before using BLE Mesh +bluetooth = Bluetooth() + +# Create a Primary Element with GATT Proxy feature and add a Server model to the Element +element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY) +model_client = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.CLIENT, callback=client_cb) + +# Initialize BLE_Mesh +BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback) + +# Turn on Provisioning Advertisement +BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT) + +print("\nBLE Mesh started") +print(BLE_Name, "waits to be provisioned\n") + +""" +# After this node was provisioned +# transmit the change of state broadcasting in the Mesh + +model_client.set_state(False, 0xFFFF) +model_client.set_state(True, 0xFFFF) + +# or to a unique server +model_client.set_state(False, 3) +model_client.set_state(True, 5) + +""" +``` + +## Sensor Example +In case of Sensor Models, State of Server can be modified only by Server itself, Client can only Get the State by calling Client's Get, or by Servers Status call, but cannot modify the Server's State. + +### Sensor Server +In this example Server takes a time measurement every 1 seconds, and send a Status message every 5 seconds, after it was provisioned. + +```python +from network import Bluetooth +import pycom +import time +from machine import Timer + +def read_sensor(alarm): + # In this example sensor reads local seconds + if(device_provisioned): + model_server.set_state(time.localtime()[5]) + print("SENSOR | State: ", model_server.get_state()) + +def status_sensor(alarm): + if (device_provisioned): + model_server.status_state() + +def prov_callback(event, oob_pass): + global device_provisioned + if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT): + # Yellow if not Provision yet or Reseted + pycom.rgbled(0x555500) + device_provisioned = False + if(event == BLE_Mesh.PROV_COMPLETE_EVT): + # Green if Provisioned + pycom.rgbled(0x007f00) + device_provisioned = True + +# BLE Mesh module +BLE_Mesh = Bluetooth.BLE_Mesh + +# Turn off the heartbeat behavior of the LED +pycom.heartbeat(False) + +# Need to turn ON Bluetooth before using BLE Mesh +bluetooth = Bluetooth() + +# Create a Primary Element with GATT Proxy feature and add a Server model to the Element +element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY) +model_server = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.SERVER, sen_min = 0, sen_max = 59, sen_res = 1) + +# Initialize BLE_Mesh +BLE_Mesh.init("Pycom Sensor Server", callback=prov_callback) + +# Turn on Provisioning Advertisement +BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT) + +# Sensor takes measurement every 1 second +Timer.Alarm(read_sensor, 1, periodic=True) + +# Sensor send status every 5 seconds +Timer.Alarm(status_sensor, 5, periodic=True) +``` + +### Sensor Client + +Sensor Client is looking for measurements, as Server sends Status every 5 seconds. Between these calls, Client can Get message any time. + +```python +from network import Bluetooth +import pycom + +def client_cb(new_state, event, recv_op): + print("CLIENT | State: ", new_state) + +def prov_callback(event, oob_pass): + if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT): + # Yellow if not Provision yet or Reseted + pycom.rgbled(0x555500) + if(event == BLE_Mesh.PROV_COMPLETE_EVT): + # Green if Provisioned + pycom.rgbled(0x007f00) + +# BLE Mesh module +BLE_Mesh = Bluetooth.BLE_Mesh + +# Turn off the heartbeat behavior of the LED +pycom.heartbeat(False) + +# Need to turn ON Bluetooth before using BLE Mesh +bluetooth = Bluetooth() + +# Create a Primary Element with GATT Proxy feature and add a Server model to the Element +element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY) +model_client = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.CLIENT, callback=client_cb, sen_min = 0, sen_max = 59, sen_res = 1) + +# Initialize BLE_Mesh +BLE_Mesh.init("Pycom Sensor Client", callback=prov_callback) + +# Turn on Provisioning Advertisement +BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT) +``` \ No newline at end of file diff --git a/content/tutorials/networks/wlan.md b/content/tutorials/networks/wlan.md index b394822..da4a899 100644 --- a/content/tutorials/networks/wlan.md +++ b/content/tutorials/networks/wlan.md @@ -27,9 +27,9 @@ Using the WLAN class from network, you can change the name (SSID) and security s ```python from network import WLAN -wlan = WLAN(mode=WLAN.AP) +wlan = WLAN(mode=WLAN.AP, ssid='hello world') -wlan.init(ssid="hello world", auth=None) +wlan.init() #use the line below to apply a password #wlan.init(ssid="hi", auth=(WLAN.WPA2, "eightletters")) print(wlan.ifconfig(id=1)) #id =1 signifies the AP interface diff --git a/content/updatefirmware/device.md b/content/updatefirmware/device.md index c6f6347..04f45b1 100644 --- a/content/updatefirmware/device.md +++ b/content/updatefirmware/device.md @@ -23,14 +23,24 @@ The basic firmware upgrade procedure can be found below, please follow these ste After you're done with upgrading, you can use the Pymakr Plugins to upload and run programs in your device. -1. Before connecting your module to a Pysense / Pytrack board, you should update the firmware on the Pysense/Pytrack board. Instructions on how to do this can be found [here](/updatefirmware/expansionboard/). +1. Before connecting your module to a Pysense / Pytrack board, you should check for updates of the firmware on the Pysense/Pytrack board. Instructions on how to do this can be found [here](/updatefirmware/expansionboard/). 2. Disconnect your device from your computer -3. Insert module into Expansion Board +3. Insert the module into Expansion Board * On Expansionboard 2.0, connect a jumper cable or wire between `G23` and `GND` 4. Reconnect the board via USB to your computer 5. Run the Firmware Upgrade tool and click through the menus -![](/gitbook/assets/firmware-update-2.png) + ![](/gitbook/assets/firmware_update-0.png) + > Checking 'Include Development Releases' will check for the development releases of the Firmware Updater Tool + + + ![](/gitbook/assets/firmware_update-1.png) + > Checking 'Show Advanced Settings' will give you the option screen in the next figure. + + ![](/gitbook/assets/firmware_update-2.png) + + > In some cases, erasing the NVS and CONFIG partitions can solve issues relating to WiFi, Timers or other variables stored in the NVS / CONFIG. Erase during update will remove all Python code on the device. + 6. The firmware version of your device is now upgraded to the latest version. * On Expansionboard 2.0, remove the jumper cable. @@ -39,7 +49,7 @@ After you're done with upgrading, you can use the Pymakr Plugins to upload and r ## Common issues: -* If you are having any issues, make sure the **TX and RX jumpers** are present on your Expansion Board, as the jumpers sometimes come loose in the box during transport. Without these jumpers, the updater will fail. +* If you are having any issues uploading firmware to your device, make sure the **TX and RX jumpers** are present on your Expansion Board, as the jumpers sometimes come loose in the box during transport. Without these jumpers, the updater will fail. * On MacOS, the firmware upgrade tool needs access to the `/tmp` folder * On MacOS, there is an issue with signing of the firmware tool. Go to system preferences --> Security & Privacy --> General, and click "Allow" for the Pycom Firmware Updater tool. diff --git a/content/updatefirmware/expansionboard.md b/content/updatefirmware/expansionboard.md index 8c6426d..865c3e5 100644 --- a/content/updatefirmware/expansionboard.md +++ b/content/updatefirmware/expansionboard.md @@ -6,122 +6,110 @@ aliases: - chapter/updatefirmware/expansionboard --- -To update the firmware on the Pysense/Pytrack/Pyscan/Expansion Board v3, please see the following instructions. The firmware of Pysense/Pytrack/Pyscan/Expansion Board v3 can be updated via the USB port using the terminal tool, `DFU-util`. +To update the firmware on any of the expansionboards, please see the following instructions. The firmware of can be updated via the USB port using the terminal tool, `DFU-util`. > There is currently **no firmware update** released for the new **Pytrack 2.0 X** and **Pysense 2.0 X**. Please do not try to flash these boards with firmware released for the old Version 1 hardware revision. The hardware revision is printed on the bottom of the shield. The latest firmware DFU file can be downloaded from the links below: - +* [Pygate](https://software.pycom.io/findupgrade?key=pygate.dfu&type=all&redirect=true) * [Pytrack 1 DFU](https://software.pycom.io/findupgrade?key=pytrack.dfu&type=all&redirect=true) * [Pysense 1 DFU](https://software.pycom.io/findupgrade?key=pysense.dfu&type=all&redirect=true) * [Expansion Board DFU v3.0](https://software.pycom.io/findupgrade?key=expansion3.dfu&type=all&redirect=true) * [Expansion Board DFU v3.1](https://software.pycom.io/findupgrade?key=expansion31.dfu&type=all&redirect=true) - > Make sure to choose the correct firmware version for your expansion board. both 3.0 and 3.1 versions have version numbers in the silkscreen on the back of the board. See the image below for examples highlighted in Red >![](/gitbook/assets/expansion_board_version.png) -While in the normal, application mode, the Pysense/Pytrack/Pyscan/Expansion Board v3 require a Serial USB CDC driver, in DFU, bootloader mode, the DFU driver is required. Below, the USB Product ID is depicted for each case. +## Product ID +In normal operation, the expansionboard is in Application mode. However when we want to update the firmware, we should put the board in DFU (Device Firmware Upgrade) mode. This is a special mode that allows us to alter the firmware of the device. Entering DFU mode changes the Product ID of the device, such that we will never accidentally update the firmware. To actually upgrade the firmware, we need to install the DFU-Util tool. Below, the USB Product ID is depicted for each case. You can check the Product ID for your board using `lsusb` on macOS and Linux, and checkin the device manager in Windows: | Board | DFU bootloader (update mode) | Application firmware (normal mode) | | :--- | :--- | :--- | +| Pygate | `0xED15` | `0xED14` | | Pytrack | `0xF014` | `0xF013` | | Pysense | `0xF011` | `0xF012` | | Pyscan | `0xEF37` | `0xEF38` | | Expansion Board v3 | `0xEF99` | `0xEF98` | -_Note: USB Vendor ID is always_ `0x04D8`_._ +_Note: USB Vendor ID is always_ `0x04D8` -## Installing the DFU-util Tools -### macOS -If using `homebrew`: +## Installing DFU-Util -```bash -$ brew install dfu-util -``` + * MacOS -If using `MacPorts`: + * If using `homebrew`: -```bash -port install libusb dfu-util -``` + ```bash + $ brew install dfu-util + ``` + * If using `MacPorts`: -### Linux + ```bash + port install libusb dfu-util + ``` + * Linux -Ubuntu or Debian: + ```bash + $ sudo apt-get install dfu-util + ``` -```bash -$ sudo apt-get install dfu-util -``` + * Windows -Fedora: + Download and install [DFU-util v0.9](http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip) + + For Windows, we will need to install separate drivers for the board to recognized as a Pycom board in DFU mode. + 1. Disconnect the USB cable to your expansion board + 2. Hold down the DFU mode button on the shield -```bash -$ sudo yum install dfu-util -``` + * [Zadig](http://zadig.akeo.ie/) – Installer tool for the Pytrack/Pysense board DFU Firmware -Arch: + To install the drivers, the board must be in DFU-mode: -```bash -$ sudo pacman -Sy dfu-util -``` + 1. Disconnect the USB cable + 2. Remove the development module from the expansionboard. + 3. Hold down the button on the shield + 4. Connect the USB cable + 5. Keep the button pressed for at least one second + 6. Release the button. When the board is connected in DFU-mode, it will be in this state for 7 seconds. + 7. Click the`“Install Driver` button immediately. If the driver was unsuccessful, repeat from step 1. + If all went sucessfully, you will see the device show up in `Device Manager` as a LibusbK device. -### Windows + ![](/gitbook/assets/pytrack_dfu_mode_zadig.png) -* [DFU-util v0.9](http://dfu-util.sourceforge.net/releases/dfu-util-0.9-win64.zip) – Tool to upload the firmware to the Pytrack/Pysense -* [Zadig](http://zadig.akeo.ie/) – Installer tool for the Pytrack/Pysense board DFU Firmware + > If you accidentally installed the `libusbk` while the device was in Application mode, then the need to update the driver to the `Serial USB (CDC)` driver has to be installed for application mode. This will allow Windows to allocate a COM port, which is required for REPL console. + > ![](/gitbook/assets/pytrack_app_mode_zadig.png) -To uploaded the latest DFU firmware to the Pytrack/Pysense, **first install the DFU drivers** to the host computer. Open Zadig and select `libusbK` as the driver. - -To install the drivers, the Pytrack/Pysense board must be in DFU-mode: - -1. Disconnect the USB cable -2. Hold down the button on the shield -3. Connect the USB cable -4. Keep the button pressed for at least one second -5. Release the button. When the board is connected in DFU-mode, it will be in this state for 7 seconds. -6. Click the`“Install Driver` button immediately. If the driver was unsuccessful, repeat from step 1. - * _Here the USB ID has to be the DFU-bootloader one (_`0xF014`_for Pytrack or_ `0xF011` _for Pysense)._ - * _This is a successful DFU driver installation for Pytrack:_ - -![](/gitbook/assets/pytrack_dfu_mode_zadig.png) - -Open the command prompt and navigate to the directory where the DFU-util and the firmware was downloaded (must be in same directory). Repeat the procedure to get the board in DFU-mode and run the command below but replace `X.X.X` with the firmware version and replace Pysense with Pytrack if it is the Pytrack that is to be updated (e.g: `pytrack_0.0.8.dfu`): - -```bash -dfu-util-static.exe -D pysense_X.X.X.dfu -``` - -If the update was successful, a message,"Done!" should appear in the bottom of the command prompt. - -**Double-check Serial USB (CDC) driver is installed in Application mode:** if, by mistake, the `libusbk` driver was installed while the USB ID is the Application mode (`0xF013` for Pytrack or `0xF012` for Pysense), then the `Serial USB (CDC)` driver has to be installed for application mode. This will allow Windows to allocate a COM port, which is required for REPL console. - -![](/gitbook/assets/pytrack_app_mode_zadig.png) - -## Using DFU-util with Pytrack, Pysense and Expansion Board v3 +## Using DFU-util To enter update mode follow these steps: -1. Unplug the device -2. Press the button and keep it held (on the Expansion Board the `S1` button) -3. Plug in the USB cable to the host computer and wait 1 second before releasing the button -4. After this you will have approximately 7 seconds to run the DFU-util tool +1. Navigate the terminal to the folder where you downloaded the `.dfu` file to +2. Unplug the device +3. Remove the development module +4. Press this button on your device: -### macOS and Linux: +| Pygate | Pysense / Pytrack | Pysense 2.0 X / Pytrack 2.0 X | Expansionboard | +|:------:|:-----------------:|:-----------------------------:|:--------------:| +| | | | | -```bash -$ dfu-util -D pytrack_0.0.8.dfu -``` -{{% hint style="info" %}} -You might need to run `dfu-util` as `sudo`. In that case, you will need to enter your password. -{{% /hint %}} +5. Plug in the USB cable to the host computer and wait 1 second before releasing the button +6. After this you will have approximately 7 seconds to run the DFU-util tool + * For MacOS and Linux: + ```bash + $ dfu-util -D pytrack_0.0.8.dfu + ``` + * For Windows: + ```bash + dfu-util-static.exe -D filename.dfu + ``` -An output, similar to the one below, will appear upon successful installation: +If the update was successful, "Done!" should appear in the bottom of the command prompt. +The output should look like the following: ```bash dfu-util 0.9 @@ -152,9 +140,9 @@ state(2) = dfuIDLE, status(0) = No error condition is present Done! ``` -#### Debugging +### Debugging -Using `lsusb` command, the Pytrack/Pysense device should be visible in both normal and bootloader modes. +Using `lsusb` command, the device should be visible in both normal and bootloader modes. For exemple, a Pytrack board is visible as either: diff --git a/content/updatefirmware/ltemodem.md b/content/updatefirmware/ltemodem.md index bb178ef..bddd567 100644 --- a/content/updatefirmware/ltemodem.md +++ b/content/updatefirmware/ltemodem.md @@ -20,9 +20,10 @@ The bottom two lines explain the LTE firmware edition: * LR5.xx is for CAT-M1 * LR6.xx is for NB-IoT -The last 5 numbers define the firmware version. A higher number represents a newer firmware. +The firmwares for CAT-M1 and NB-IoT are fundamentally different and cannot be used interchangable. The last 5 numbers define the firmware version. A higher number represents a newer firmware. +> Our newest products ship with firmware version CatM1 47510. There is no major difference between the latest public version 41065 and 47510. -> Note: The prefered method for updating the LTE modem is using upgdiff- files, as these updates are faster. Check in the zip archive wheter a upgdiff- update for your version is available. When using a upgdiff- file, you do not need to use `updater.elf` +The prefered method for updating the LTE modem is using `upgdiff-` files, as these updates are faster. Check in the zip archive wheter a upgdiff- update for your version is available. When using a `upgdiff-` file, you do not need to use `updater.elf` > Using `sqnsupgrade` does not currently work properly in the pygate firmware @@ -34,8 +35,8 @@ There are several different ways to update the firmware of the LTE modem. >Note: In case of any failure or interruption to the process of LTE modem upgrade you can repeat the same steps **after doing a hard reset to the board (i.e disconnecting and reconnecting power), pressing the reset button is not enough.** -The modem firmware files are password protected. In order to download them, head to https://forum.pycom.io and become a member (if you aren't already) and click on: -Announcements & News --> Announcements for members only --> the Firmware Files for the Sequans LTE modem are now secured to retrieve the credentials. You can find the firmwares listed [here](https://software.pycom.io/downloads/sequans2.html). +The modem firmware files are password protected. In order to download them, head to https://forum.pycom.io and become a member (if you aren't already) and go [here](https://forum.pycom.io/topic/4020/firmware-files-for-sequans-lte-modem-now-are-secured) for the credentials. (On the forum: Announcements & News --> Announcements for members only --> the Firmware Files) +You can find the firmwares listed [here](https://software.pycom.io/downloads/sequans2.html). ## Flash @@ -76,7 +77,7 @@ Announcements & News --> Announcements for members only --> the Firmware Files f sqnsupgrade.run('/sd/upgdiff_old-to-new.dup') # if no upgdiff is available, run the following instead # sqnsupgrade.run('/sd/name.dup') - # WARNING! If you are updating from version 33080, use the updater.elf file as well + # WARNING! If you are updating from version 33080, use the updater.elf file as well, this is not needed for the upgdiff file. # sqnsupgrade.run('/sd/name.dup', '/sd/updater.elf') ``` @@ -105,8 +106,10 @@ If you do not have an SD card available, you can use the existing USB-UART inter ```python $ python3 >>> import sqnsupgrade - >>> sqnsupgrade.run('Serial_Port', '/path/to/name.dup') - # WARNING! If you are updating from version 33080, use the updater.elf file as well + >>> sqnsupgrade.run('Serial_Port', '/path/to/upgdiff_old-to-new.dup') + # If no upgdiff file is available, use the following + # >>> sqnsupgrade.run('Serial_Port', '/path/to/name.dup') + # WARNING! If you are updating from version 33080, use the updater.elf file as well, this is not needed for the upgdiff file # >>> sqnsupgrade.run('Serial_Port', '/path/to/name.dup', '/path/to/updater.elf') ``` >Note: Replace the paths and `name.dup` with the actual files. There are different versions for `CAT-M1` and `NB-IoT` diff --git a/content/updatefirmware/ota.md b/content/updatefirmware/ota.md index dc1d882..05774f6 100644 --- a/content/updatefirmware/ota.md +++ b/content/updatefirmware/ota.md @@ -14,6 +14,16 @@ Pycom modules come with the ability to update the devices firmware, while it is 2. Click on the configuration tab 3. Use the OTA firmware update tool there + +Before we talk about OTA, we need to first discuss the inner workings of the `bootmgr` and partitioning. The (modern) Pycom devices all have 16MB flash, divided across different partitions: + +| Factory () | Firmware (~3MB) | OTA () | Python code () | Free () | +|------|--------------|-----|-------|----| + +Using the function `pycom.bootmgr()`, we can switch between the different boot partitions. This way, we can upload a new firmware to the device and then reboot, with the boot partition switched from `pycom.FACTORY` to `pycom.OTA_0` to load the updated firmware. We can do this using the functions: +`pycom.ota_start()` `pycom.ota_write()`, `pycom.ota_finish()` and `pycom.ota_verify()`. + + ## Method A Here we will describe one possible update methodology you could use that is implemented by this example. diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index ebe3b45..8755986 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -36,6 +36,7 @@ - + {{- partial "alexia.html" . -}} {{- partial "google_analitycs.html" . -}} + + diff --git a/layouts/shortcodes/development.html b/layouts/shortcodes/development.html new file mode 100644 index 0000000..6147c6e --- /dev/null +++ b/layouts/shortcodes/development.html @@ -0,0 +1,13 @@ +{{ $_hugo_config := `{ "version": 1 }` }} +
+ + + Development version {{.Get "version" }} + {{ .Inner }} + + + +
+ + + diff --git a/layouts/shortcodes/hint.html b/layouts/shortcodes/hint.html index 28cb6f7..0eb5999 100644 --- a/layouts/shortcodes/hint.html +++ b/layouts/shortcodes/hint.html @@ -1,5 +1,7 @@ - +{{ $_hugo_config := `{ "version": 1 }` }} + {{ .Inner }} + diff --git a/static/gitbook/assets/RoHs_declarations/RoHS-for-Expansion Board(8286-00033P)-20190523.pdf b/static/gitbook/assets/RoHs_declarations/RoHS-for-Expansion-Board(8286-00033P)-20190523.pdf similarity index 100% rename from static/gitbook/assets/RoHs_declarations/RoHS-for-Expansion Board(8286-00033P)-20190523.pdf rename to static/gitbook/assets/RoHs_declarations/RoHS-for-Expansion-Board(8286-00033P)-20190523.pdf diff --git a/static/gitbook/assets/c03-b0-red-final-g01.pdf b/static/gitbook/assets/c03-b0-red-final-g01.pdf new file mode 100644 index 0000000..a90629d Binary files /dev/null and b/static/gitbook/assets/c03-b0-red-final-g01.pdf differ diff --git a/static/gitbook/assets/deepsleep-image-1.jpg b/static/gitbook/assets/deepsleep-image-1.jpg index 17456d5..234bb17 100644 Binary files a/static/gitbook/assets/deepsleep-image-1.jpg and b/static/gitbook/assets/deepsleep-image-1.jpg differ diff --git a/static/gitbook/assets/fipy-1.png b/static/gitbook/assets/fipy-1.png index 6c1e2d3..f8d737b 100644 Binary files a/static/gitbook/assets/fipy-1.png and b/static/gitbook/assets/fipy-1.png differ diff --git a/static/gitbook/assets/firmware-update-2.png b/static/gitbook/assets/firmware-update-2.png deleted file mode 100644 index 214c855..0000000 Binary files a/static/gitbook/assets/firmware-update-2.png and /dev/null differ diff --git a/static/gitbook/assets/firmware-update.png b/static/gitbook/assets/firmware-update.png deleted file mode 100644 index e04b57e..0000000 Binary files a/static/gitbook/assets/firmware-update.png and /dev/null differ diff --git a/static/gitbook/assets/firmware_update-0.png b/static/gitbook/assets/firmware_update-0.png new file mode 100644 index 0000000..29127a1 Binary files /dev/null and b/static/gitbook/assets/firmware_update-0.png differ diff --git a/static/gitbook/assets/firmware_update-1.png b/static/gitbook/assets/firmware_update-1.png new file mode 100644 index 0000000..34bc961 Binary files /dev/null and b/static/gitbook/assets/firmware_update-1.png differ diff --git a/static/gitbook/assets/firmware_update-2.png b/static/gitbook/assets/firmware_update-2.png new file mode 100644 index 0000000..f87e6a4 Binary files /dev/null and b/static/gitbook/assets/firmware_update-2.png differ diff --git a/static/gitbook/assets/g01-1.png b/static/gitbook/assets/g01-1.png index c87911b..9e1251c 100644 Binary files a/static/gitbook/assets/g01-1.png and b/static/gitbook/assets/g01-1.png differ diff --git a/static/gitbook/assets/gpy-1.png b/static/gitbook/assets/gpy-1.png index f611ccb..9230ba4 100644 Binary files a/static/gitbook/assets/gpy-1.png and b/static/gitbook/assets/gpy-1.png differ diff --git a/static/gitbook/assets/l01-1.png b/static/gitbook/assets/l01-1.png index 4d328bc..66c609d 100644 Binary files a/static/gitbook/assets/l01-1.png and b/static/gitbook/assets/l01-1.png differ diff --git a/static/gitbook/assets/l01-reference.png b/static/gitbook/assets/l01-reference.png index cec4d2e..754c17b 100644 Binary files a/static/gitbook/assets/l01-reference.png and b/static/gitbook/assets/l01-reference.png differ diff --git a/static/gitbook/assets/l01.png b/static/gitbook/assets/l01.png index 4d328bc..a12a056 100644 Binary files a/static/gitbook/assets/l01.png and b/static/gitbook/assets/l01.png differ diff --git a/static/gitbook/assets/l04-1.png b/static/gitbook/assets/l04-1.png index 89f0030..b1e4784 100644 Binary files a/static/gitbook/assets/l04-1.png and b/static/gitbook/assets/l04-1.png differ diff --git a/static/gitbook/assets/lopy-1.png b/static/gitbook/assets/lopy-1.png index 350f4fe..08efdb3 100644 Binary files a/static/gitbook/assets/lopy-1.png and b/static/gitbook/assets/lopy-1.png differ diff --git a/static/gitbook/assets/lopy4-1.png b/static/gitbook/assets/lopy4-1.png index cc0edd5..f0a75cd 100644 Binary files a/static/gitbook/assets/lopy4-1.png and b/static/gitbook/assets/lopy4-1.png differ diff --git a/static/gitbook/assets/oem_universal_ref.png b/static/gitbook/assets/oem_universal_ref.png index 2729a06..96a1dda 100644 Binary files a/static/gitbook/assets/oem_universal_ref.png and b/static/gitbook/assets/oem_universal_ref.png differ diff --git a/static/gitbook/assets/pybytes/ml/data_acquisition.png b/static/gitbook/assets/pybytes/ml/data_acquisition.png new file mode 100644 index 0000000..0227326 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/data_acquisition.png differ diff --git a/static/gitbook/assets/pybytes/ml/data_acquisition_graph.png b/static/gitbook/assets/pybytes/ml/data_acquisition_graph.png new file mode 100644 index 0000000..67a8c3f Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/data_acquisition_graph.png differ diff --git a/static/gitbook/assets/pybytes/ml/deploy.png b/static/gitbook/assets/pybytes/ml/deploy.png new file mode 100644 index 0000000..cd6d264 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/deploy.png differ diff --git a/static/gitbook/assets/pybytes/ml/ml_page.png b/static/gitbook/assets/pybytes/ml/ml_page.png new file mode 100644 index 0000000..fc24240 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/ml_page.png differ diff --git a/static/gitbook/assets/pybytes/ml/model_config.png b/static/gitbook/assets/pybytes/ml/model_config.png new file mode 100644 index 0000000..9fc27c1 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/model_config.png differ diff --git a/static/gitbook/assets/pybytes/ml/model_created.png b/static/gitbook/assets/pybytes/ml/model_created.png new file mode 100644 index 0000000..7cf7afd Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/model_created.png differ diff --git a/static/gitbook/assets/pybytes/ml/model_definition.png b/static/gitbook/assets/pybytes/ml/model_definition.png new file mode 100644 index 0000000..8758393 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/model_definition.png differ diff --git a/static/gitbook/assets/pybytes/ml/model_main_page.png b/static/gitbook/assets/pybytes/ml/model_main_page.png new file mode 100644 index 0000000..d331418 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/model_main_page.png differ diff --git a/static/gitbook/assets/pybytes/ml/processing.png b/static/gitbook/assets/pybytes/ml/processing.png new file mode 100644 index 0000000..2962598 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/processing.png differ diff --git a/static/gitbook/assets/pybytes/ml/processing_output.png b/static/gitbook/assets/pybytes/ml/processing_output.png new file mode 100644 index 0000000..525d596 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/processing_output.png differ diff --git a/static/gitbook/assets/pybytes/ml/pybytes_front_page.png b/static/gitbook/assets/pybytes/ml/pybytes_front_page.png new file mode 100644 index 0000000..c5dd32c Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/pybytes_front_page.png differ diff --git a/static/gitbook/assets/pybytes/ml/select_device.png b/static/gitbook/assets/pybytes/ml/select_device.png new file mode 100644 index 0000000..1a0ff2b Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/select_device.png differ diff --git a/static/gitbook/assets/pybytes/ml/testing.png b/static/gitbook/assets/pybytes/ml/testing.png new file mode 100644 index 0000000..8d34946 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/testing.png differ diff --git a/static/gitbook/assets/pybytes/ml/testing_results.png b/static/gitbook/assets/pybytes/ml/testing_results.png new file mode 100644 index 0000000..b0d0415 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/testing_results.png differ diff --git a/static/gitbook/assets/pybytes/ml/training.png b/static/gitbook/assets/pybytes/ml/training.png new file mode 100644 index 0000000..6251800 Binary files /dev/null and b/static/gitbook/assets/pybytes/ml/training.png differ diff --git a/static/gitbook/assets/pyethernet.png b/static/gitbook/assets/pyethernet.png index 3f8a465..605387d 100644 Binary files a/static/gitbook/assets/pyethernet.png and b/static/gitbook/assets/pyethernet.png differ diff --git a/static/gitbook/assets/pyscan-new.png b/static/gitbook/assets/pyscan-new.png index 5773b38..709dc92 100644 Binary files a/static/gitbook/assets/pyscan-new.png and b/static/gitbook/assets/pyscan-new.png differ diff --git a/static/gitbook/assets/pyscan-pinout-1.png b/static/gitbook/assets/pyscan-pinout-1.png index 1b598fa..6208b7b 100644 Binary files a/static/gitbook/assets/pyscan-pinout-1.png and b/static/gitbook/assets/pyscan-pinout-1.png differ diff --git a/static/gitbook/assets/pysense2_desc.png b/static/gitbook/assets/pysense2_desc.png index f78eab8..d183efb 100644 Binary files a/static/gitbook/assets/pysense2_desc.png and b/static/gitbook/assets/pysense2_desc.png differ diff --git a/static/gitbook/assets/pytrack2_decs.png b/static/gitbook/assets/pytrack2_decs.png index 3f20da9..05cc5ba 100644 Binary files a/static/gitbook/assets/pytrack2_decs.png and b/static/gitbook/assets/pytrack2_decs.png differ diff --git a/static/gitbook/assets/sipy-2.png b/static/gitbook/assets/sipy-2.png index 0fcd18d..8d51b41 100644 Binary files a/static/gitbook/assets/sipy-2.png and b/static/gitbook/assets/sipy-2.png differ diff --git a/static/gitbook/assets/universal_reference.png b/static/gitbook/assets/universal_reference.png index a232c1a..09ebc0d 100644 Binary files a/static/gitbook/assets/universal_reference.png and b/static/gitbook/assets/universal_reference.png differ diff --git a/static/gitbook/assets/w01.png b/static/gitbook/assets/w01.png index ad3091e..025c017 100644 Binary files a/static/gitbook/assets/w01.png and b/static/gitbook/assets/w01.png differ diff --git a/static/gitbook/assets/wipy2-1.png b/static/gitbook/assets/wipy2-1.png deleted file mode 100644 index 962b10c..0000000 Binary files a/static/gitbook/assets/wipy2-1.png and /dev/null differ diff --git a/static/gitbook/assets/wipy2.png b/static/gitbook/assets/wipy2.png index 05bd828..8d02032 100644 Binary files a/static/gitbook/assets/wipy2.png and b/static/gitbook/assets/wipy2.png differ diff --git a/static/gitbook/assets/wipy3.png b/static/gitbook/assets/wipy3.png index 3e68385..63ce55c 100644 Binary files a/static/gitbook/assets/wipy3.png and b/static/gitbook/assets/wipy3.png differ diff --git a/themes/doc-theme/static/css/doc-theme.css b/themes/doc-theme/static/css/doc-theme.css index a1bc81f..9fa57a9 100644 --- a/themes/doc-theme/static/css/doc-theme.css +++ b/themes/doc-theme/static/css/doc-theme.css @@ -220,6 +220,21 @@ li.hot { padding:0!important; } +/* changes 19-08-2020 +Added shortcode for development markings + +*/ +.development { + display:none; + +} +.dev { + background-color: #F6E6D6 !important; +} + +.v-card__text > h3, h4{ + margin-top:0px; +} .danger-alert { background-color: #EF9A9A !important; margin-top: 24px; @@ -340,7 +355,7 @@ code { } .primary--text { - color: green; /*#00cc96; */ + color: #00cc96; } .v-window { diff --git a/themes/doc-theme/static/css/vuetify.css b/themes/doc-theme/static/css/vuetify.css index 6434f1f..55386cc 100644 --- a/themes/doc-theme/static/css/vuetify.css +++ b/themes/doc-theme/static/css/vuetify.css @@ -2824,6 +2824,9 @@ ol { padding-left: 24px; margin-bottom: 10px; } +li p{ + margin-bottom: 0px; +} .display-4 { font-size: 112px !important; font-weight: 300;