Merge branch 'development-publish' into pymesh2

This commit is contained in:
Catalin Ioana
2019-11-05 11:20:49 +02:00
committed by GitHub
51 changed files with 955 additions and 458 deletions

View File

@@ -1,12 +1,12 @@
version: 0.1
version: 0.2
frontend:
phases:
build:
commands:
- wget https://github.com/gohugoio/hugo/releases/download/v0.54.0/hugo_0.54.0_Linux-64bit.tar.gz
- tar -xf hugo_0.54.0_Linux-64bit.tar.gz hugo
- wget https://github.com/gohugoio/hugo/releases/download/v0.58.3/hugo_0.58.3_Linux-64bit.tar.gz
- tar -xf hugo_0.58.3_Linux-64bit.tar.gz hugo
- mv hugo /usr/bin/hugo
- rm -rf hugo_0.54.0_Linux-64bit.tar.gz
- rm -rf hugo_0.58.3_Linux-64bit.tar.gz
- hugo
artifacts:
baseDirectory: public

View File

@@ -1,4 +1,4 @@
baseURL = "https://docs.pycom.io/"
baseURL = "https://development.pycom.io/"
languageCode = "en-us"
title = "documentation"
uglyurls = false
@@ -198,12 +198,12 @@ theme = "doc-theme"
parent = "gettingstarted@registration@lora"
weight = 10
# [[menu.main]]
# name = "Objenious"
# url = "/gettingstarted/registration/lora/objenious/"
# identifier = "gettingstarted@registration@lora@objenious"
# parent = "gettingstarted@registration@lora"
# weight = 20
[[menu.main]]
name = "Objenious"
url = "/gettingstarted/registration/lora/objenious/"
identifier = "gettingstarted@registration@lora@objenious"
parent = "gettingstarted@registration@lora"
weight = 20
# *** Pymakr Plugin
[[menu.main]]
@@ -338,6 +338,13 @@ theme = "doc-theme"
parent = "tutorials@all"
weight = 10
[[menu.main]]
name = "PyGate"
url = "/tutorials/all/PyGate/"
identifier = "tutorials@all@PyGate"
parent = "tutorials@all"
weight = 10
[[menu.main]]
name = "WLAN"
url = "/tutorials/all/wlan/"
@@ -520,6 +527,20 @@ theme = "doc-theme"
parent = "tutorials@lora"
weight = 70
[[menu.main]]
name = "LoRa Mesh"
url = "/tutorials/lora/lora-mesh/"
identifier = "tutorials@lora@lora-mesh"
parent = "tutorials@lora"
weight = 80
[[menu.main]]
name = "PyMesh Border Router"
url = "/tutorials/lora/pymesh-br/"
identifier = "tutorials@lora@pymesh-br"
parent = "tutorials@lora"
weight = 90
[[menu.main]]
name = "Sigfox Examples"
url = "/tutorials/sigfox/"
@@ -611,26 +632,26 @@ theme = "doc-theme"
parent = "firmwareapi@pycom@machine"
weight = 10
[[menu.main]]
name = "CAN"
url = "/firmwareapi/pycom/machine/can/"
identifier = "firmwareapi@pycom@machine@can"
parent = "firmwareapi@pycom@machine"
weight = 20
[[menu.main]]
name = "DAC"
url = "/firmwareapi/pycom/machine/dac/"
identifier = "firmwareapi@pycom@machine@dac"
parent = "firmwareapi@pycom@machine"
weight = 20
weight = 30
[[menu.main]]
name = "I2C"
url = "/firmwareapi/pycom/machine/i2c/"
identifier = "firmwareapi@pycom@machine@i2c"
parent = "firmwareapi@pycom@machine"
weight = 30
[[menu.main]]
name = "Pin"
url = "/firmwareapi/pycom/machine/pin/"
identifier = "firmwareapi@pycom@machine@pin"
parent = "firmwareapi@pycom@machine"
weight = 40
weight = 35
[[menu.main]]
name = "PWM"
@@ -640,58 +661,58 @@ theme = "doc-theme"
weight = 50
[[menu.main]]
name = "RTC"
url = "/firmwareapi/pycom/machine/rtc/"
identifier = "firmwareapi@pycom@machine@rtc"
name = "Pin"
url = "/firmwareapi/pycom/machine/pin/"
identifier = "firmwareapi@pycom@machine@pin"
parent = "firmwareapi@pycom@machine"
weight = 60
[[menu.main]]
name = "SPI"
url = "/firmwareapi/pycom/machine/spi/"
identifier = "firmwareapi@pycom@machine@spi"
name = "RMT"
url = "/firmwareapi/pycom/machine/rmt/"
identifier = "firmwareapi@pycom@machine@rmt"
parent = "firmwareapi@pycom@machine"
weight = 70
[[menu.main]]
name = "UART"
url = "/firmwareapi/pycom/machine/uart/"
identifier = "firmwareapi@pycom@machine@uart"
name = "RTC"
url = "/firmwareapi/pycom/machine/rtc/"
identifier = "firmwareapi@pycom@machine@rtc"
parent = "firmwareapi@pycom@machine"
weight = 80
[[menu.main]]
name = "WDT"
url = "/firmwareapi/pycom/machine/wdt/"
identifier = "firmwareapi@pycom@machine@wdt"
parent = "firmwareapi@pycom@machine"
weight = 90
[[menu.main]]
name = "Timer"
url = "/firmwareapi/pycom/machine/timer/"
identifier = "firmwareapi@pycom@machine@timer"
parent = "firmwareapi@pycom@machine"
weight = 100
[[menu.main]]
name = "SD"
url = "/firmwareapi/pycom/machine/sd/"
identifier = "firmwareapi@pycom@machine@sd"
parent = "firmwareapi@pycom@machine"
weight = 90
[[menu.main]]
name = "SPI"
url = "/firmwareapi/pycom/machine/spi/"
identifier = "firmwareapi@pycom@machine@spi"
parent = "firmwareapi@pycom@machine"
weight = 100
[[menu.main]]
name = "Timer"
url = "/firmwareapi/pycom/machine/timer/"
identifier = "firmwareapi@pycom@machine@timer"
parent = "firmwareapi@pycom@machine"
weight = 110
[[menu.main]]
name = "CAN"
url = "/firmwareapi/pycom/machine/can/"
identifier = "firmwareapi@pycom@machine@can"
name = "UART"
url = "/firmwareapi/pycom/machine/uart/"
identifier = "firmwareapi@pycom@machine@uart"
parent = "firmwareapi@pycom@machine"
weight = 120
[[menu.main]]
name = "RMT"
url = "/firmwareapi/pycom/machine/rmt/"
identifier = "firmwareapi@pycom@machine@rmt"
name = "WDT"
url = "/firmwareapi/pycom/machine/wdt/"
identifier = "firmwareapi@pycom@machine@wdt"
parent = "firmwareapi@pycom@machine"
weight = 130
@@ -934,7 +955,6 @@ theme = "doc-theme"
parent = "firmwareapi@micropython"
weight = 90
# [Errno 2] No such file or directory: './content/firmwareapi/micropython/ustruct/README.md'
[[menu.main]]
name = "ustruct"
url = "/firmwareapi/micropython/ustruct/"
@@ -942,6 +962,13 @@ theme = "doc-theme"
parent = "firmwareapi@micropython"
weight = 180
[[menu.main]]
name = "uzlib"
url = "/firmwareapi/micropython/uzlib/"
identifier = "firmwareapi@micropython@uzlib"
parent = "firmwareapi@micropython"
weight = 200
[[menu.main]]
name = "_thread"
url = "/firmwareapi/micropython/_thread/"

BIN
content/.DS_Store vendored

Binary file not shown.

View File

@@ -4,7 +4,6 @@ aliases:
- advance/downgrade.html
- advance/downgrade.md
- chapter/advance/downgrade
---
The firmware upgrade tool usually updates your device to the latest available firmware version. If you require to downgrade your device to a previous firmware there are two methods to achieve this.

View File

@@ -15,14 +15,12 @@ The Pycom documentation follows standard Python Library format using the popular
The values of the arguments (as seen in the examples/docs) refer to the default values that are passed into the constructor if nothing is provided.
```python
i2c.init(mode, * , baudrate=100000, pins=(SDA, SCL))
```
An example of what this method might be called:
```python
i2c.init(I2C.MASTER, pins=('P12', 'P11'))
```
@@ -37,12 +35,10 @@ It is important to note that there are certain class methods that can only accep
An asterisk `*` in a method description \(in the docs\), denotes that the following arguments require a keyword, i.e. `pin='P16'` in the example below.
```python
adc.channel(* , pin, attn=ADC.ATTN_0DB)
```
```python
from machine import ADC
adc = ADC() # create an ADC object
@@ -54,7 +50,6 @@ apin = adc.channel(pin='P16') # create an analog pin on P16
Another example shows how the `PWM` class, `pwm.channel()` requires a keyword argument for `pin` but does not for `id`.
```python
from machine import PWM
pwm = PWM(0, frequency=5000)
@@ -66,14 +61,12 @@ pwm_c = pwm.channel(0, pin='P12') # no keyword argument required for id (0) but
The documentation may refer to a method that takes an argument listed by name but does allow for a keyword to be passed. For example, the `pycom` class contains a method `rgbled`. This lists that the method accepts a value for `color`, however this may not be specified by `keyword`, only `value`. This is intentional as the `value` being passed is the only argument valid for this method
```python
pycom.rgbled(color)
```
If the argument is passed into the method with a keyword, it will return an error stating TypeError: function does not take keyword arguments.
```python
import pycom
pycom.rgbled(color=0xFF0000) # Incorrect
@@ -83,12 +76,10 @@ pycom.rgbled(0xFF0000) # Correct
Another example of a method that only accepts value input. In this case, the `RTC.init()` method require a value (`tuple`) input for the `datetime`. It will not accept a keyword.
```python
rtc.init(datetime)
```
```python
from machine import RTC
rtc = RTC()
@@ -101,7 +92,6 @@ rtc.init((2014, 5, 1, 4, 13, 0, 0, 0)) # Correct
The `constants` section of a library within the docs refers to specific values from that library's class. These might be used when constructing an object from that class or when utilising a method from within that class. These are generally listed by the library name followed by the specific value. See the example below:
```python
I2C.MASTER()
```

View File

@@ -15,7 +15,6 @@ AES is implemented using the ESP32 hardware module.
## Quick Usage Example
```python
from crypto import AES
import crypto
key = b'notsuchsecretkey' # 128 bit (16 bytes) key

View File

@@ -46,15 +46,26 @@ Returns CPU frequency in hertz.
Gates the clock to the CPU, useful to reduce power consumption at any time during short or long periods. Peripherals continue working and execution resumes as soon as any interrupt is triggered (on many ports this includes system timer interrupt occurring at regular intervals on the order of millisecond).
#### machine.sleep(\[time\_ms\], resume\_wifi\_ble)
Sets the device in to light sleep mode , where in this mode digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
* `time_ms` is the time in milliseconds that the device should wakeup after, if no time is given the device will sleep until the next reset cycle unless another wakeup source is configured.
* `resume_wifi_ble` is a boolean value that enables or disable restoring after wakeup any WiFi or BLE connection that was interrupted by light sleep.
* `True` Enable WiFi/BLE connections restoration
* `False` Disable Wifi/BLE connections restoration, default option is Disabled
_Note: in light sleep mode LoRa/Lte modems are stopped and have to be re-initialized after wakeup._
#### machine.deepsleep(\[time\_ms\])
Stops the CPU and all peripherals, including the networking interfaces (except for LTE). Execution is resumed from the main script, just as with a reset. If a value in milliseconds is given then the device will wake up after that period of time, otherwise it will remain in deep sleep until the reset button is pressed.
The products with LTE connectivity (FiPy, GPy, G01), require the LTE radio to be disabled separately via the LTE class before entering deepsleep. This is required due to the LTE radio being powered independently and allowing use cases which require the system to be taken out from deepsleep by an event from the LTE network (data or SMS received for instance).
#### machine.pin\_deepsleep\_wakeup(pins, mode, enable\_pull)
#### machine.pin\_sleep\_wakeup(pins, mode, enable\_pull)
Configure pins to wake up from deep sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
Configure pins to wake up from deep/light sleep mode. The pins which have this capability are: `P2, P3, P4, P6, P8 to P10 and P13 to P23`.
The arguments are:

View File

@@ -85,6 +85,24 @@ Returns `True` if the last `ntp_sync` has been completed, `False` otherwise:
rtc.synced()
```
#### rtc.memory(\[data\])
Reads RTC memory contents or write data in passed Buffer in to RTC memory
Example:
```python
rtc = RTC()
rtc.memory(b'10101010') # writes data in RTC memory
rtc.memory()
```
Output:
```python
b'10101010'
```
## Constants
* Clock source: `RTC.INTERNAL_RC`, `RTC.XTAL_32KHZ`

View File

@@ -72,7 +72,6 @@ Get the elapsed time in microseconds.
Example:
```python
from machine import Timer
import time
@@ -111,7 +110,6 @@ Disables the alarm.
Example:
```python
from machine import Timer
class Clock:

View File

@@ -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))
#### 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:
@@ -93,6 +93,7 @@ Initialise the UART bus with the given parameters:
* `stop` is the number of stop bits, `1 or 2`.
* `timeout_chars` Rx timeout defined in number of characters. The value given here will be multiplied by the time a characters takes to be transmitted at the configured `baudrate`.
* `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()

View File

@@ -1,271 +0,0 @@
---
title: "Bluetooth"
aliases:
- chapter/firmwareapi/pycom/network/bluetooth
---
search: false
---
# Bluetooth
This class provides a driver for the Bluetooth radio in the module. Currently, only basic BLE functionality is available.
## Quick Usage Example
```python
from network import Bluetooth
import time
bt = Bluetooth()
bt.start_scan(-1)
while True:
adv = bt.get_adv()
if adv and bt.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL) == 'Heart Rate':
try:
conn = bt.connect(adv.mac)
services = conn.services()
for service in services:
time.sleep(0.050)
if type(service.uuid()) == bytes:
print('Reading chars from service = {}'.format(service.uuid()))
else:
print('Reading chars from service = %x' % service.uuid())
chars = service.characteristics()
for char in chars:
if (char.properties() & Bluetooth.PROP_READ):
print('char {} value = {}'.format(char.uuid(), char.read()))
conn.disconnect()
break
except:
print("Error while connecting or reading from the BLE device")
break
else:
time.sleep(0.050)
```
## Bluetooth Low Energy (BLE)
Bluetooth low energy (BLE) is a subset of classic Bluetooth, designed for easy connecting and communicating between devices (in particular mobile platforms). BLE uses a methodology known as Generic Access Profile (GAP) to control connections and advertising.
GAP allows for devices to take various roles but generic flow works with devices that are either a Server (low power, resource constrained, sending small payloads of data) or a Client device (commonly a mobile device, PC or Pycom Device with large resources and processing power). Pycom devices can act as both a Client and a Server.
## Constructors
### class network.Bluetooth(id=0, ...)
Create a Bluetooth object, and optionally configure it. See init for params of configuration.
Example:
```python
from network import Bluetooth
bluetooth = Bluetooth()
```
## Methods
### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None)
* `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`.
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()
Disables the Bluetooth radio.
### 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.
The arguments are:
* `timeout` specifies the amount of time in seconds to scan for advertisements, cannot be zero. If timeout is > 0, then the BLE radio will listen for advertisements until the specified value in seconds elapses. If timeout < 0, then there's no timeout at all, and stop\_scan() needs to be called to cancel the scanning process.
Examples:
```python
bluetooth.start_scan(10) # starts scanning and stop after 10 seconds
bluetooth.start_scan(-1) # starts scanning indefinitely until bluetooth.stop_scan() is called
```
### bluetooth.stop\_scan()
Stops an ongoing scanning process. Returns `None`.
### bluetooth.isscanning()
Returns `True` if a Bluetooth scan is in progress. `False` otherwise.
### 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)`
* `mac` is the 6-byte ling mac address of the device that sent the advertisement.
* `addr_type` is the address type. See the constants section below for more details.
* `adv_type` is the advertisement type received. See the constants section below fro more details.
* `rssi` is signed integer with the signal strength of the advertisement.
* `data` contains the complete 31 bytes of the advertisement message. In order to parse the data and get the specific types, the method `resolve_adv_data()` can be used.
Example for getting `mac` address of an advertiser:
```python
import ubinascii
bluetooth = Bluetooth()
bluetooth.start_scan(20) # scan for 20 seconds
adv = bluetooth.get_adv() #
ubinascii.hexlify(adv.mac) # convert hexadecimal to ascii
```
### 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)
Parses the advertisement data and returns the requested `data_type` if present. If the data type is not present, the function returns `None`.
Arguments:
* `data` is the bytes object with the complete advertisement data.
* `data_type` is the data type to resolve from from the advertisement data. See constants section below for details.
Example:
```python
import ubinascii
from network import Bluetooth
bluetooth = Bluetooth()
bluetooth.start_scan(20)
while bluetooth.isscanning():
adv = bluetooth.get_adv()
if adv:
# try to get the complete name
print(bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_NAME_CMPL))
mfg_data = bluetooth.resolve_adv_data(adv.data, Bluetooth.ADV_MANUFACTURER_DATA)
if mfg_data:
# try to get the manufacturer data (Apple's iBeacon data is sent here)
print(ubinascii.hexlify(mfg_data))
```
### bluetooth.connect(mac\_addr)
Opens a BLE connection with the device specified by the `mac_addr` argument. This function blocks until the connection succeeds or fails. If the connections succeeds it returns a object of type `GATTCConnection`.
Connections are initiated by the central device. There is a maximum of 4 simultaneous connections.
```python
bluetooth.connect('112233eeddff') # mac address is accepted as a string
```
### bluetooth.callback(trigger=None, handler=None, arg=None)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
* `trigger` can be either `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, or `Bluetooth.CLIENT_DISCONNECTED`
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given the bluetooth object itself is used.
An example of how this may be used can be seen in the [`bluetooth.events()`](./#bluetooth-events) method.
### bluetooth.events()
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
Example of usage:
```python
from network import Bluetooth
bluetooth = Bluetooth()
bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456')
def conn_cb (bt_o):
events = bt_o.events() # this method returns the flags and clears the internal registry
if events & Bluetooth.CLIENT_CONNECTED:
print("Client connected")
elif events & Bluetooth.CLIENT_DISCONNECTED:
print("Client disconnected")
bluetooth.callback(trigger=Bluetooth.CLIENT_CONNECTED | Bluetooth.CLIENT_DISCONNECTED, handler=conn_cb)
bluetooth.advertise(True)
```
### 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.
The arguments are:
* `name` is the string name to be shown on advertisements.
* `manufacturer_data` manufacturer data to be advertised (hint: use it for iBeacons).
* `service_data` service data to be advertised.
* `service_uuid` uuid of the service to be advertised.
Example:
```python
bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")
```
### 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)
Create a new service on the internal GATT server. Returns a object of type `BluetoothServerService`.
The arguments are:
* `uuid` is the UUID of the service. Can take an integer or a 16 byte long string or bytes object.
* `isprimary` selects if the service is a primary one. Takes a `bool` value.
* `nbr_chars` specifies the number of characteristics that the service will contain.
* `start` if `True` the service is started immediately.
```python
bluetooth.service('abc123')
```
### bluetooth.disconnect\_client()
Closes the BLE connection with the client.
## Constants
* Bluetooth mode: `Bluetooth.BLE`
* Advertisement type: `Bluetooth.CONN_ADV`, `Bluetooth.CONN_DIR_ADV`, `Bluetooth.DISC_ADV`, `Bluetooth.NON_CONN_ADV`, `Bluetooth.SCAN_RSP`
* Address type: `Bluetooth.PUBLIC_ADDR`, `Bluetooth.RANDOM_ADDR`, `Bluetooth.PUBLIC_RPA_ADDR`, `Bluetooth.RANDOM_RPA_ADDR`
* Advertisement data type: `Bluetooth.ADV_FLAG`, `Bluetooth.ADV_16SRV_PART`, `Bluetooth.ADV_T16SRV_CMPL`, `Bluetooth.ADV_32SRV_PART`, `Bluetooth.ADV_32SRV_CMPL`, `Bluetooth.ADV_128SRV_PART`, `Bluetooth.ADV_128SRV_CMPL`, `Bluetooth.ADV_NAME_SHORT`, `Bluetooth.ADV_NAME_CMPL`, `Bluetooth.ADV_TX_PWR`, `Bluetooth.ADV_DEV_CLASS`, `Bluetooth.ADV_SERVICE_DATA`, `Bluetooth.ADV_APPEARANCE`, `Bluetooth.ADV_ADV_INT`, `Bluetooth.ADV_32SERVICE_DATA`, `Bluetooth.ADV_128SERVICE_DATA`, `Bluetooth.ADV_MANUFACTURER_DATA`
* Characteristic properties (bit values that can be combined): `Bluetooth.PROP_BROADCAST`, `Bluetooth.PROP_READ`, `Bluetooth.PROP_WRITE_NR`, `Bluetooth.PROP_WRITE`, `Bluetooth.PROP_NOTIFY`, `Bluetooth.PROP_INDICATE`, `Bluetooth.PROP_AUTH`, `Bluetooth.PROP_EXT_PROP`
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`

View File

@@ -1,6 +1,7 @@
---
title: "Bluetooth"
aliases:
- chapter/firmwareapi/pycom/network/bluetooth
---
This class provides a driver for the Bluetooth radio in the module. Currently, only basic BLE functionality is available.
@@ -46,45 +47,37 @@ GAP allows for devices to take various roles but generic flow works with devices
## Constructors
### class network.Bluetooth(id=0, ...)
#### class network.Bluetooth(id=0, ...)
Create a Bluetooth object, and optionally configure it. See init for params of configuration.
Example:
```python
from network import Bluetooth
bluetooth = Bluetooth()
```
## Methods
### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None, secure=False)
#### bluetooth.init(id=0, mode=Bluetooth.BLE, antenna=None, modem\_sleep=True, secure=False, pin=123456)
* `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`.
* `secure` enables or disables the GATT Server security features.
* `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 features
* `pin` a six digit number to connect to the GATT Sever
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.
@@ -95,20 +88,19 @@ The arguments are:
Examples:
```python
bluetooth.start_scan(10) # starts scanning and stop after 10 seconds
bluetooth.start_scan(-1) # starts scanning indefinitely until bluetooth.stop_scan() is called
```
### bluetooth.stop\_scan()
#### bluetooth.stop\_scan()
Stops an ongoing scanning process. Returns `None`.
### bluetooth.isscanning()
#### bluetooth.isscanning()
Returns `True` if a Bluetooth scan is in progress. `False` otherwise.
### bluetooth.get\_adv()
#### bluetooth.get\_adv()
Gets an named tuple with the advertisement data received during the scanning. The tuple has the following structure: `(mac, addr_type, adv_type, rssi, data)`
@@ -121,7 +113,6 @@ Gets an named tuple with the advertisement data received during the scanning. Th
Example for getting `mac` address of an advertiser:
```python
import ubinascii
bluetooth = Bluetooth()
@@ -131,11 +122,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`.
@@ -147,7 +138,6 @@ Arguments:
Example:
```python
import ubinascii
from network import Bluetooth
bluetooth = Bluetooth()
@@ -166,18 +156,16 @@ while bluetooth.isscanning():
print(ubinascii.hexlify(mfg_data))
```
### bluetooth.connect(mac\_addr)
#### bluetooth.connect(mac\_addr, timeout=None)
Opens a BLE connection with the device specified by the `mac_addr` argument. This function blocks until the connection succeeds or fails. If the connections succeeds it returns a object of type `GATTCConnection`.
Connections are initiated by the central device. There is a maximum of 4 simultaneous connections.
* `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`.
```python
bluetooth.connect('112233eeddff') # mac address is accepted as a string
```
### bluetooth.callback(trigger=None, handler=None, arg=None)
#### bluetooth.callback(trigger=None, handler=None, arg=None)
Creates a callback that will be executed when any of the triggers occurs. The arguments are:
@@ -187,14 +175,13 @@ Creates a callback that will be executed when any of the triggers occurs. The ar
An example of how this may be used can be seen in the [`bluetooth.events()`](./#bluetooth-events) method.
### bluetooth.events()
#### bluetooth.events()
Returns a value with bit flags identifying the events that have occurred since the last call. Calling this function clears the events.
Example of usage:
```python
from network import Bluetooth
bluetooth = Bluetooth()
@@ -212,7 +199,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.
@@ -226,15 +213,27 @@ The arguments are:
Example:
```python
bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")
```
### bluetooth.advertise(\[Enable\])
#### 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.
The arguments are:
* `adv_int_min` is the minimum advertising interval for undirected and low duty cycle directed advertising.
* `adv_int_max` is the maximum advertising interval for undirected and low duty cycle directed advertising.
* `adv_type` is the advertising type.
* `own_addr_type` is the owner bluetooth device address type.
* `channel_map` is the advertising channel map.
* `adv_filter_policy` is the advertising filter policy.
#### 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`.
@@ -246,20 +245,35 @@ The arguments are:
* `start` if `True` the service is started immediately.
```python
bluetooth.service('abc123')
```
### bluetooth.disconnect\_client()
#### bluetooth.disconnect\_client()
Closes the BLE connection with the client.
### 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.
If both `type` and `level` parameters are given, it sets the TX Power.
Valid values for `type`: `Bluetooth.TX_PWR_CONN` -> for handling connection, `Bluetooth.TX_PWR_ADV` -> for advertising, `Bluetooth.TX_PWR_SCAN` -> for scan, `Bluetooth.TX_PWR_DEFAULT` -> default, if others not set
Valid values for `level`: Bluetooth.TX_PWR_N12` -> -12dbm, `Bluetooth.TX_PWR_N9` -> -9dbm, `Bluetooth.TX_PWR_N6` -> -6dbm, `Bluetooth.TX_PWR_N3` -> -3dbm, `Bluetooth.TX_PWR_0` -> 0dbm, `Bluetooth.TX_PWR_P3` -> 3dbm, `Bluetooth.TX_PWR_P6` -> 6dbm, `Bluetooth.TX_PWR_P9` -> 9dbm
## Constants
* Bluetooth mode: `Bluetooth.BLE`
* Advertisement type: `Bluetooth.CONN_ADV`, `Bluetooth.CONN_DIR_ADV`, `Bluetooth.DISC_ADV`, `Bluetooth.NON_CONN_ADV`, `Bluetooth.SCAN_RSP`
* Address type: `Bluetooth.PUBLIC_ADDR`, `Bluetooth.RANDOM_ADDR`, `Bluetooth.PUBLIC_RPA_ADDR`, `Bluetooth.RANDOM_RPA_ADDR`
* Advertisement data type: `Bluetooth.ADV_FLAG`, `Bluetooth.ADV_16SRV_PART`, `Bluetooth.ADV_T16SRV_CMPL`, `Bluetooth.ADV_32SRV_PART`, `Bluetooth.ADV_32SRV_CMPL`, `Bluetooth.ADV_128SRV_PART`, `Bluetooth.ADV_128SRV_CMPL`, `Bluetooth.ADV_NAME_SHORT`, `Bluetooth.ADV_NAME_CMPL`, `Bluetooth.ADV_TX_PWR`, `Bluetooth.ADV_DEV_CLASS`, `Bluetooth.ADV_SERVICE_DATA`, `Bluetooth.ADV_APPEARANCE`, `Bluetooth.ADV_ADV_INT`, `Bluetooth.ADV_32SERVICE_DATA`, `Bluetooth.ADV_128SERVICE_DATA`, `Bluetooth.ADV_MANUFACTURER_DATA`
* Advertisement parameters: `Bluetooth.ADV_TYPE_IND`, `Bluetooth.ADV_TYPE_DIRECT_IND_HIGH`, `Bluetooth.ADV_TYPE_SCAN_IND`, `Bluetooth.ADV_TYPE_NONCONN_IND`, `Bluetooth.ADV_TYPE_DIRECT_IND_LOW`, `Bluetooth.ADV_BLE_ADDR_TYPE_PUBLIC`, `Bluetooth.ADV_BLE_ADDR_TYPE_RANDOM`, `Bluetooth.ADV_BLE_ADDR_TYPE_RPA_PUBLIC`, `Bluetooth.ADV_BLE_ADDR_TYPE_RPA_RANDOM`, `Bluetooth.ADV_CHNL_37`, `Bluetooth.ADV_CHNL_38`, `Bluetooth.ADV_CHNL_39`, `Bluetooth.ADV_CHNL_ALL`, `Bluetooth.ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY`, `Bluetooth.ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY`, `Bluetooth.ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST`, `Bluetooth.ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST`
* Characteristic properties (bit values that can be combined): `Bluetooth.PROP_BROADCAST`, `Bluetooth.PROP_READ`, `Bluetooth.PROP_WRITE_NR`, `Bluetooth.PROP_WRITE`, `Bluetooth.PROP_NOTIFY`, `Bluetooth.PROP_INDICATE`, `Bluetooth.PROP_AUTH`, `Bluetooth.PROP_EXT_PROP`
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`
* TX Power type: `Bluetooth.TX_PWR_CONN`, `Bluetooth.TX_PWR_ADV`, `Bluetooth.TX_PWR_SCAN`, `Bluetooth.TX_PWR_DEFAULT`
* TX Power level: `Bluetooth.TX_PWR_N12`, `Bluetooth.TX_PWR_N9`, `Bluetooth.TX_PWR_N6`, `Bluetooth.TX_PWR_N3`, `Bluetooth.TX_PWR_0`, `Bluetooth.TX_PWR_P3`, `Bluetooth.TX_PWR_P6`, `Bluetooth.TX_PWR_P9`
## Exceptions
* `Bluetooth.timeout`

View File

@@ -48,3 +48,25 @@ This method allows to register for notifications on the characteristic.
* `handler` is the function that will be executed when the callback is triggered.
* `arg` is the argument that gets passed to the callback. If nothing is given, the characteristic object that owns the callback will be used.
#### characteristic.read\_descriptor(uuid)
Returns the value of the descriptor specified by the `uuid` parameter. If no descriptor found for the characteristic returns None.
```python
descriptor = char.read_descriptor(0x2900)
if(descriptor != None):
print("Characteristic Extended Properties: " + str(binascii.hexlify((descriptor))))
descriptor = char.read_descriptor(0x2901)
if(descriptor != None):
print("Characteristic User Description: " + str(binascii.hexlify((descriptor))))
descriptor = char.read_descriptor(0x2902)
if(descriptor != None):
print("Client Characteristic Configuration: " + str(binascii.hexlify((descriptor))))
descriptor = char.read_descriptor(0x2904)
if(descriptor != None):
print("Characteristic Presentation Format: " + str(binascii.hexlify((descriptor))))
```

View File

@@ -9,12 +9,11 @@ aliases:
Sigfox is a Low Power Wide Area Network protocol that enables remote devices to connect using ultra-narrow band, UNB technology. The protocol is bi-directional, messages can both be sent up to and down from the Sigfox servers.
{{% hint style="info" %}}
When operating in RCZ2 and RCZ4 the module can only send messages on the default macro-channel (this is due to Sigfox network limitations). Therefore, the device needs to reset automatically to the default macro-channel after every 2 transmissions. However, due to FCC duty cycle limitations, there must a minimum of a 20s delay after resetting to the default macro-channel. Our API takes care of this, (and in real life applications you should not be in the need to send Sigfox messages that often), so it will wait for the necessary amount of time to make sure that the duty cycle restrictions are fulfilled.
When operating in `RCZ2` and `RCZ4` the module can only send messages on the default macro-channel (this is due to Sigfox network limitations). Therefore, the device needs to reset automatically to the default macro-channel after every 2 transmissions. However, due to FCC duty cycle limitations, there must a minimum of a 20s delay after resetting to the default macro-channel. Our API takes care of this, (and in real life applications you should not be in the need to send Sigfox messages that often), so it will wait for the necessary amount of time to make sure that the duty cycle restrictions are fulfilled.
This means that if you run a piece of test code like:
```python
for i in range(1, 100):
# send something
s.send('Hello ' + str(i))
@@ -28,7 +27,6 @@ This class provides a driver for the Sigfox network processor in the Sigfox enab
## Quick Usage Example
```python
from network import Sigfox
import socket
@@ -59,7 +57,6 @@ Please ensure that there is an antenna connected to your device before sending/r
Create and configure a Sigfox object. See init for params of configuration. Examples:
```python
# configure radio for the Sigfox network, using RCZ1 (868 MHz)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
@@ -68,7 +65,7 @@ sigfox = Sigfox(mode=Sigfox.FSK, frequency=912000000)
```
{{% hint style="info" %}}
Sigfox.FSK mode is not supported on LoPy 4 and FiPy.
`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{{% /hint %}}
## Methods
@@ -107,7 +104,6 @@ Returns a byte object with the 8-Byte bytes object with the Sigfox PAC.
To return human-readable values you should import `ubinascii` and convert binary values to hexidecimal representation. For example:
```python
print(ubinascii.hexlify(sigfox.mac()))
```
{{% /hint %}}
@@ -121,7 +117,6 @@ Returns a tuple of the form: `(uplink_frequency_hz, downlink_frequency_hz)`
Sets or gets the public key flag. When called passing a `True` value the Sigfox public key will be used to encrypt the packets. Calling it without arguments returns the state of the flag.
```python
# enable encrypted packets
sigfox.public_key(True)
@@ -145,7 +140,6 @@ sigfox.public_key()
Sigfox sockets are created in the following way:
```python
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
```
@@ -163,7 +157,6 @@ Use it to close an existing socket.
In Sigfox mode the maximum data size is 12 bytes. In FSK the maximum is 64.
```python
# send a Sigfox payload of bytes
s.send(bytes([1, 2, 3]))
@@ -176,7 +169,6 @@ s.send('Hello')
This method can be used to receive a Sigfox downlink or FSK message.
```python
# size of buffer should be passed for expected payload, e.g. 64 bytes
s.recv(64)
```
@@ -186,7 +178,6 @@ s.recv(64)
Set the value of the given socket option. The needed symbolic constants are defined in the socket module (`SO_*` etc.). In the case of Sigfox the values are always an integer. Examples:
```python
# wait for a downlink after sending the uplink packet
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
@@ -206,7 +197,6 @@ s.setsockopt(socket.SOL_SIGFOX, socket.SO_BIT, False)
Sending a Sigfox packet with a single bit is achieved by sending an empty string, i.e.:
```python
import socket
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
@@ -228,14 +218,12 @@ If the socket is set to blocking, your code will be wait until the socket comple
A Sigfox capable Pycom devices (SiPy) can both send and receive data from the Sigfox network. To receive data, a message must first be sent up to Sigfox, requesting a downlink message. This can be done by passing a `True` argument into the `setsockopt()` method.
```python
s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, True)
```
An example of the downlink procedure can be seen below:
```python
# init Sigfox for RCZ1 (Europe)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1)
@@ -260,13 +248,12 @@ s.recv(32)
To communicate between two Sigfox capable devices, it may be used in FSK mode. Two devices are required to be set to the same frequency, both using FSK.
{{% hint style="info" %}}
Sigfox.FSK mode is not supported on LoPy 4 and FiPy.
`Sigfox.FSK` mode is not supported on LoPy 4 and FiPy.
{{% /hint %}}
**Device 1**:
```python
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
@@ -281,7 +268,6 @@ while True:
**Device 2**:
```python
sigfox = Sigfox(mode=Sigfox.FSK, frequency=868000000)
s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)

View File

@@ -5,11 +5,9 @@ aliases:
- firmwareapi/pycom/network/wlan.md
- chapter/firmwareapi/pycom/network/wlan
---
This class provides a driver for the WiFi network processor in the module. Example usage:
```python
import network
import time
# setup as a station
@@ -25,7 +23,6 @@ print(wlan.ifconfig())
## Quick Usage Example
```python
import machine
from network import WLAN
@@ -42,9 +39,9 @@ print(wlan.ifconfig())
## Constructors
#### class network.WLAN(id=0, ...)
### class network.WLAN(id=0, ...)
Create a WLAN object, and optionally configure it. See [`init`](../wlan.md#wlan-init-mode-ssid-none-auth-none-channel-1-antenna-none-power_save-false-hidden-false) for params of configuration.
Create a WLAN object, and optionally configure it. See [`init`](../wlan#wlan-init-mode-ssid-none-auth-none-channel-1-antenna-none-power_save-false-hidden-false) for params of configuration.
{{% hint style="info" %}}
The WLAN constructor is special in the sense that if no arguments besides the `id` are given, it will return the already existing WLAN instance without re-configuring it. This is because WLAN is a system feature of the WiPy. If the already existing instance is not initialised it will do the same as the other constructors an will initialise it with default values.
@@ -52,7 +49,7 @@ The WLAN constructor is special in the sense that if no arguments besides the `i
## Methods
#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False)
#### wlan.init(mode, \* , ssid=None, auth=None, channel=1, antenna=None, power\_save=False, hidden=False, bandwidth=HT40, max\_tx\_pwr=20, country=CN)
Set or get the WiFi network processor configuration.
@@ -69,11 +66,13 @@ Arguments are:
* `power_save` enables or disables power save functions in `STA` mode.
* `hidden` only valid in `WLAN.AP` mode to create an access point with a hidden SSID when set to `True`.
* `bandwidth` is the Bandwidth to use, either 20MHz or 40 MHz , use `HT20` or `HT40`
* `max_tx_pwr` is the maximum WiFi Tx power allowed. see `WLAN.max_tx_power()` for more details
* `country` tuple representing the country configuration parameters. see `WLAN.country()` for more details
For example, you can do:
```python
# create and configure as an access point
wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channel=7, antenna=WLAN.INT_ANT)
```
@@ -81,25 +80,15 @@ wlan.init(mode=WLAN.AP, ssid='wipy-wlan', auth=(WLAN.WPA2,'www.wipy.io'), channe
or
```python
# configure as an station
wlan.init(mode=WLAN.STA)
```
{{% hint style="info" %}}
To use an external antenna, set `P12 as output pin.`
```python
Pin('P12', mode=Pin.OUT)(True)
```
{{% /hint %}}
#### wlan.deinit()
### wlan.deinit()
Disables the WiFi radio.
#### wlan.connect(ssid, \* , auth=None, bssid=None, timeout=None, ca\_certs=None, keyfile=None, certfile=None, identity=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.
@@ -112,24 +101,48 @@ Connect to a wifi access point using the given SSID, and other security paramete
* `keyfile` is the path to the client key. Only used if `username` and `password` are not part of the `auth` tuple.
* `certfile` is the path to the client certificate. Only used if `username` and `password` are not part of the `auth` tuple.
* `identity` is only used in case of `WLAN.WPA2_ENT` security. Needed by the server.
* `hostname` is the name of the host connecting to the AP. Max length of name string is 32 Bytes
{{% hint style="info" %}}
The ESP32 only handles certificates with `pkcs8` format (but not the "Traditional SSLeay RSAPrivateKey" format). The private key should be RSA coded with 2048 bits at maximum.
{{% /hint %}}
#### wlan.scan()
#### wlan.scan(\[ssid=NULL, bssid=NULL, 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)`. Note that channel is always `None` since this info is not provided by the WiPy.
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.
#### wlan.disconnect()
Note: For Fast scan mode ssid/bssid and channel should be
* `ssid` : If the SSID is not NULL, it is only the AP with the same SSID that can be scanned.
* `bssid` : If the BSSID is not NULL, it is only the AP with the same BSSID that can be scanned. The bssid is given as 6 Hexadecimal bytes literals (i.e b'\xff\xff\xff\xff\xff\xff')
* `channel` : If “channel” is 0, there will be an all-channel scan; otherwise, there will be a specific-channel scan.
* `show_hidden` : If “show\_hidden” is 0, the scan ignores the AP with a hidden SSID; otherwise, the scan considers the hidden AP a normal one.
* `type` : If “type” is `WLAN.SCAN_ACTIVE`, the scan is “active”; otherwise, it is a “passive” one.
* Active Scan is performed by sending a probe request. The default scan is an active scan
* Passive Scan sends no probe request. Just switch to the specific channel and wait for a beacon.
* `scantime` :
This field is used to control how long the scan dwells on each channel. For passive scans, scantime=\[int\] designates the dwell time for each channel.
For active scans, dwell times for each channel are listed below. scantime is given as a tuple for min and max times (min,max)
min=0, max=0: scan dwells on each channel for 120 ms.
min>0, max=0: scan dwells on each channel for 120 ms.
min=0, max>0: scan dwells on each channel for max ms.
min>0, max>0: The minimum time the scan dwells on each channel is min ms. If no AP is found during this time frame, the scan switches to the next channel. Otherwise, the scan dwells on the channel for max ms.If you want to improve the performance of the the scan, you can try to modify these two parameters.
### wlan.disconnect()
Disconnect from the WiFi access point.
#### wlan.isconnected()
### wlan.isconnected()
In case of STA mode, returns `True` if connected to a WiFi access point and has a valid IP address. In AP mode returns `True` when a station is connected, `False` otherwise.
#### wlan.ifconfig(id=0, config=\['dhcp' or configtuple\])
### wlan.ifconfig(id=0, config=\['dhcp' or configtuple\])
When `id` is 0, the configuration will be get/set on the Station interface. When `id` is 1 the configuration will be done for the AP interface.
@@ -140,45 +153,240 @@ If `dhcp` is passed as a parameter then the DHCP client is enabled and the IP pa
If the 4-tuple config is given then a static IP is configured. For instance:
```python
wlan.ifconfig(config=('192.168.0.4', '255.255.255.0', '192.168.0.1', '8.8.8.8'))
```
#### wlan.mode(\[mode\])
### wlan.mode(\[mode\])
Get or set the WLAN mode.
#### wlan.ssid(\[ssid\])
### wlan.ssid(\[ssid\])
Get or set the SSID when in AP mode.
Get or set the SSID (Set SSID of AP).
#### wlan.auth(\[auth\])
In case if mode = `WLAN.STA` this method can get the ssid of AP the board is connected to.
In case of mode = `WLAN.AP` this method can get the ssid of the board's own AP.
In case of mode = `WLAN.STA_AP` this method can get the ssid of board's own AP plus the AP the STA is connected to in form of a tuple:
_\_
### wlan.auth(\[auth\])
Get or set the authentication type when in AP mode.
#### wlan.channel(\[channel\])
### wlan.channel(\[channel, sec\_chn\])
Get or set the channel (only applicable in AP mode).
_In AP mode:_
#### wlan.antenna(\[antenna\])
Get or set the wifi channel
_In STA mode:_
`channel`: is the primary channel to listen to.
`sec_chn` : Only in case of Bandwidth = HT40 this should specify the position of the secondary channel weather above or below primary channel. `WLAN.SEC_CHN_POS_ABOVE` or `WLAN.SEC_CHN_POS_BELOW`
_Note: Setting Channel in STA mode is only Allowed in Promiscuous mode_
### wlan.antenna(\[antenna\])
Get or set the antenna type (external or internal).
{{% hint style="info" %}}
To use an external antenna, set `P12 as output pin.`
### wlan.mac(\[mac, mode\])
when no arguments are passed a 6-byte long `bytes` tuple object with the WiFI MAC address of both Wifi Station mode and Acces Point mode
`mac`: a 6 bytes bytearray mac address
`mode`: The Interface to set the given MAC address to `WLAN.STA` or `WLAN.AP`
Ex: To set the mac address of Wifi Station mode:
```python
Pin('P12', mode=Pin.OUT)(True)
wlan.mac(bytearray([0xAE, 0x77, 0x88, 0x99, 0x22, 0x44]), WLAN.STA)
```
{{% /hint %}}
#### wlan.mac()
_Note: STA and AP cannot have the Same Mac Address_
Get a 6-byte long `bytes` object with the WiFI MAC address.
### wlan.bandwidth()
Set the bandwidth of the wifi, either 20 MHz or 40 MHz can be configured, use constants `HT20` or `HT40`
### wlan.hostname()
Set the Host name of the device connecting to the AP in case of Wifi `mode=WLAN.STA`, in case of `mode=WLAN.AP` this is the name of the host hosting the AP. Max length of name string is 32 Bytes
### wlan.ap\_sta\_list()
Gets an info list of all stations connected to the board's AP.
Info returned is a list of tuples containning (\[mac address of connected STA\], \[average rssi value\], \[Wlan protocol enabled by STA\]).
Protocol types are either : `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N` or `WLAN.PHY_LOW_RATE`
### wlan.max\_tx\_power(\[power\])
Gets or Sets the maximum allowable transmission power for wifi.
Packets of different rates are transmitted in different powers according to the configuration in phy init data. This API only sets maximum WiFi transmiting power. If this API is called, the transmiting power of every packet will be less than or equal to the value set by this API. Default is Level 0.
Values passed in power are mapped to transmit power levels as follows:
* \[78, 127\]: level0
* \[76, 77\]: level1
* \[74, 75\]: level2
* \[68, 73\]: level3
* \[60, 67\]: level4
* \[52, 59\]: level5
* \[44, 51\]: level5 - 2dBm
* \[34, 43\]: level5 - 4.5dBm
* \[28, 33\]: level5 - 6dBm
* \[20, 27\]: level5 - 8dBm
* \[8, 19\]: level5 - 11dBm
* \[-128, 7\]: level5 - 14dBm
### wlan.country(\[country, schan, nchan, max\_tx\_pwr, policy\])
Gets or set s Country configuration parameters for wifi.
* `country` That is the country name code , it is max 2 characters string representing the country eg: "CN" for china nad "NL" for Netherlands
* `scahn` is the start channel number, in scan process scanning will be performed starting from this channels till the total number of channels. it should be less than or equal 14.
* `nchan` is the total number of channels in the specified country. maximum is 14
* `max_tx_pwr` Maximum transmission power allowed. see `WLAN.max_tx_power()` for more details.
* `policy` Is the method when setting country configuration for `WLAN.COUNTRY_POL_AUTO` in STA mode the wifi will aquire the same country config of the connected AP, for `WLAN.COUNTRY_POL_MAN` the configured country parameters will take effect regardless of Connected AP.
### wlan.joined\_ap\_info()
Returns a tuple with (bssid, ssid, primary channel, rssi, Authorization method, wifi standard used) of the connected AP in case of STA mode.
### wlan.wifi\_protocol(\[(bool PHY11\_\_B, bool PHY11\_G, bool PHY11\_N)\])
Sets or gets Wifi Protocol supported.
### wlan.send\_raw(Buffer, interface=STA, use\_sys\_seq=True)
Send raw data through the Wifi Interface.
`Buffer`: Buffer of bytes object Containning Data to be transmitted. Data should not be greater than 1500 nor smaller than 24.
`interface`: The Interface to use for transmitting Data AP or STA in case the mode used is APSTA. other wise the interface currently active will be used.
`use_sys_seq`: `True` to use the systems next sequance number for sending the data, `False` for keeping the sequance number in the given raw data buffer unchanged.
### wlan.callback(trigger, handler=Null, arg=Null)
Register a user callback function `handler` to be called once any of the `trigger` events occures optionally with a passed `arg`. by default the wlan obj is passed as arg to the handler. To unregister the callback you can call the `wlan.callback` function with empty `handler` and `arg` parameters.
For trigger events see `Constants` section.
### wlan.promiscuous(\[bool\])
* To enable Promiscuous mode `WLAN.promiscuous(True)` should be called, and `WLAN.promiscuous(False)` for disabling
* To get current mode setting call function with empty args
Note:
* Promiscuous mode should be enabled for Wifi packets types Events to be triggered
* for changing wifi channel via `wlan.channel()` promiscuous mode should be enabled.
Example using promoscious mode:
```python
from network import WLAN
import ubinascii
def pack_cb(pack):
mac = bytearray(6)
pk = wlan.wifi_packet()
control = pk.data[0]
subtype = (0xF0 & control) >> 4
type = 0x0C & control
#print("Control:{}, subtype:{}, type:{}".format(control, subtype, type))
if subtype == 4:
for i in range (0,6):
mac[i] = pk.data[10 + i]
print ("Wifi Node with MAC: {}".format(ubinascii.hexlify(mac)))
wlan = WLAN(mode=WLAN.STA, antenna=WLAN.EXT_ANT)
wlan.callback(trigger=WLAN.EVENT_PKT_MGMT, handler=pack_cb)
wlan.promiscuous(True)
```
### wlan.events()
This function will return an integer object as mask for triggered events.
### wlan.wifi\_packet()
This function will return a tuble with Wifi packet info captured in promiscuous mode.
### wlan.ctrl\_pkt\_filter(\[int\])
This function is used to set the filter mask for Wifi control packets in promiscuous mode. for Filter masks, see `Constants` section.
To get the current Filter mask, call the function with empty args.
### 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\)
- 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.
### wlan.Connected\_ap\_pwd()
Get the password of AP the Device is connected to.
## Constants
* WLAN mode: `WLAN.STA`, `WLAN.AP`, `WLAN.STA_AP`
* WLAN network security: `WLAN.WEP`, `WLAN.WPA`, `WLAN.WPA2`, `WLAN.WPA2_ENT`
* Antenna type: `WLAN.INT_ANT`, `WLAN.EXT_ANT`
* WLAN Bandwidth: `WLAN.HT20`, `WLAN.HT40`
* WLAN protocol: `WLAN.PHY_11_B`, `WLAN.PHY_11_G`, `WLAN.PHY_11_N`, `WLAN.PHY_LOW_RATE`
* Scan Type: `WLAN.SCAN_ACTIVE` `WLAN.SCAN_PASSIVE`
* WLAN country config policy: `WLAN.COUNTRY_POL_AUTO`, `WLAN.COUNTRY_POL_MAN`
* Secondary Channel position: `WLAN.SEC_CHN_POS_ABOVE`, `WLAN.SEC_CHN_POS_BELOW`
* Wlan callback triggers:
`WLAN.EVENT_PKT_MGMT`: Managment packet recieved in promiscuous mode.
`WLAN.EVENT_PKT_CTRL`: Control Packet recieved in promiscuous mode
`WLAN.EVENT_PKT_DATA`: Data packet recieved in promiscuous mode
`WLAN.EVENT_PKT_DATA_MPDU`: MPDU data packet recieved in promiscuous mode
`WLAN.EVENT_PKT_DATA_AMPDU`: AMPDU data packet recieved in promiscuous mode
`WLAN.EVENT_PKT_MISC`: misc paket recieved in promiscuous mode.
`WLAN.EVENT_PKT_ANY`: Any packet recieved in promiscuous mode.
`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

View File

@@ -11,7 +11,6 @@ The `pycom` module contains functions to control specific features of the Pycom
## Quick Usage Example
```python
import pycom
pycom.heartbeat(False) # disable the heartbeat LED
@@ -22,11 +21,11 @@ pycom.rgbled(0xff00) # make the LED light up in green color
## Methods
#### pycom.heartbeat(\[enable\])
#### pycom.heartbeat\(\[boolean\]\)
Get or set the state (enabled or disabled) of the heartbeat LED. Accepts and returns boolean values (`True` or `False`).
#### pycom.heartbeat\_on\_boot(\[enable\])
#### 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.
@@ -39,7 +38,6 @@ Set the colour of the RGB LED. The colour is specified as 24 bit value represent
Set the value of the specified key in the NVRAM memory area of the external flash. Data stored here is preserved across resets and power cycles. Value can only take 32-bit integers at the moment. Example:
```python
import pycom
pycom.nvs_set('temp', 25)
@@ -51,7 +49,6 @@ pycom.nvs_set('count', 10)
Get the value the specified key from the NVRAM memory area of the external flash. Example:
```python
import pycom
pulses = pycom.nvs_get('count')
@@ -67,50 +64,78 @@ Erase the given key from the NVRAM memory area.
Erase the entire NVRAM memory area.
#### pycom.wifi\_on\_boot(\[enable\])
#### pycom.wifi\_on\_boot\(\[boolean\]\)
Get or set the WiFi on boot flag. When this flag is set to `True`, the AP with the default SSID (`lopy-wlan-xxx` for example) will be enabled as part of the boot process. If the flag is set to False, the module will boot with WiFi disabled until it's enabled by the script via the `WLAN` class. This setting is stored in non-volatile memory which preserves it across resets and power cycles. Example:
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.wdt\_on\_boot(\[enable\])
#### pycom.wifi\_ssid\_sta\([ssid]\)
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.
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
```python
#### pycom.wifi\_ssid\_ap\([ssid]\)
import pycom
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-\<last\_4\_digits\_mac\>\) will be used.This setting is stored in non-volatile memory which preserves it across resets and power cycles
pycom.wdt_on_boot(True) # enable WDT on boot
pycom.wdt_on_boot() # get the WDT on boot flag
```
#### 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.pulses\_get(pin, timeout)
#### 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.
Example:
```python
# get the raw data from a DHT11/DHT22/AM2302 sensor
from machine import Pin
from pycom import pulses_get
@@ -134,7 +159,6 @@ Perform a firmware update. These methods are internally used by a firmware updat
Example:
```python
# Firmware update by reading the image from the SD card
#
from pycom import ota_start, ota_write, ota_finish
@@ -165,3 +189,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.

View File

@@ -16,8 +16,6 @@ In order to connect your LoRa capable Pycom module to a LoRaWAN network you will
Firstly you will need to get your modules `Device EUI`, this can be achieved using the following code:
```python
from network import LoRa
import ubinascii

View File

@@ -41,4 +41,3 @@ Read more how to use Sigfox with [devKit contract](devkit).
Read more how to use Sigfox with [Custom contract](devkit).
{{% refname "custom.md" %}}

View File

@@ -18,6 +18,8 @@ Pymesh works on all of our LoRa supporting development boards, the LoPy4 and FiP
_**Note: For obtaining the Pymesh firmware please follow the steps from [Pymesh LICENCE page](/pymesh/licence).**_
_**Note: For obtaining the Pymesh firmware please follow the steps from [Pymesh LICENCE page](/pymesh/licence).**_
## What does Pymesh offer you?
* An ad-hoc communication network over raw-LoRa radio

View File

@@ -0,0 +1,261 @@
## Pygate
__For Starting Pygate and connecting it to a LoRa server , you need to__
1- Have a pycom Device (Wipy, LoPy4, GPy) attached to the Pygate Board (The RGB LED should be on the same side as the usb port of PyGate)
2- Attach LoRa Antenna to Pygate Board
3- Flash the Pycom Device with latest PyGate Firmware.
4- Upload the Gateway configuration json file on the attached pycom device (via Pymakr or VsCode) , Depending on the type of Pygate (EU868/US915) you should have different config files.
__In the following example we will demonstrate a simple script for getting started with Pygate using Wifi connection for EU868 region:__
you can use that same file you just need to put your GW unique ID , LoRa server adresse and port numbers
```python
from network import WLAN
import time
import machine
from machine import RTC
import pycom
#Disable Hearbeat
pycom.heartbeat(False)
#Define callback function for Pygate Events
def machine_cb (arg):
evt = machine.events()
if (evt & machine.PYGATE_START_EVT):
# Green
pycom.rgbled(0x103300)
elif (evt & machine.PYGATE_ERROR_EVT):
# Red
pycom.rgbled(0x331000)
elif (evt & machine.PYGATE_STOP_EVT):
# RGB off
pycom.rgbled(0x000000)
# register Callback func
machine.callback(trigger = (machine.PYGATE_START_EVT |
machine.PYGATE_STOP_EVT | machine.PYGATE_ERROR_EVT), handler=machine_cb)
# Connect to a Wifi Network
wlan = WLAN(mode=WLAN.STA)
wlan.connect(ssid='<SSID>', auth=(WLAN.WPA2, "<PASSWORD>"))
while not wlan.isconnected():
time.sleep(1)
print("Wifi Connection established")
#Sync time via NTP server for GW timestamps on Events
rtc = RTC()
rtc.ntp_sync(server="0.nl.pool.ntp.org")
#Read the GW config file from Filesystem
fp = open('/flash/config.json','r')
buf = fp.read()
# Start Pygate
machine.pygate_init(buf)
```
Sample Config json file for GW configuration on EU868 region:
```json
{
"SX1301_conf": {
"lorawan_public": true,
"clksrc": 1,
"antenna_gain": 0,
"radio_0": {
"enable": true,
"type": "SX1257",
"freq": 867500000,
"rssi_offset": -164.0,
"tx_enable": true,
"tx_freq_min": 863000000,
"tx_freq_max": 870000000
},
"radio_1": {
"enable": true,
"type": "SX1257",
"freq": 868500000,
"rssi_offset": -164.0,
"tx_enable": false
},
"chan_multiSF_0": {
"enable": true,
"radio": 1,
"if": -400000
},
"chan_multiSF_1": {
"enable": true,
"radio": 1,
"if": -200000
},
"chan_multiSF_2": {
"enable": true,
"radio": 1,
"if": 0
},
"chan_multiSF_3": {
"enable": true,
"radio": 0,
"if": -400000
},
"chan_multiSF_4": {
"enable": true,
"radio": 0,
"if": -200000
},
"chan_multiSF_5": {
"enable": true,
"radio": 0,
"if": 0
},
"chan_multiSF_6": {
"enable": true,
"radio": 0,
"if": 200000
},
"chan_multiSF_7": {
"enable": true,
"radio": 0,
"if": 400000
},
"chan_Lora_std": {
"enable": true,
"radio": 1,
"if": -200000,
"bandwidth": 250000,
"spread_factor": 7
},
"chan_FSK": {
"enable": true,
"radio": 1,
"if": 300000,
"bandwidth": 125000,
"datarate": 50000
},
"tx_lut_0": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_1": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_2": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_3": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_4": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_5": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_6": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 9,
"dig_gain": 3
},
"tx_lut_7": {
"pa_gain": 0,
"mix_gain": 6,
"rf_power": 11,
"dig_gain": 3
},
"tx_lut_8": {
"pa_gain": 0,
"mix_gain": 5,
"rf_power": 13,
"dig_gain": 2
},
"tx_lut_9": {
"pa_gain": 0,
"mix_gain": 8,
"rf_power": 14,
"dig_gain": 3
},
"tx_lut_10": {
"pa_gain": 0,
"mix_gain": 6,
"rf_power": 15,
"dig_gain": 2
},
"tx_lut_11": {
"pa_gain": 0,
"mix_gain": 6,
"rf_power": 16,
"dig_gain": 1
},
"tx_lut_12": {
"pa_gain": 0,
"mix_gain": 9,
"rf_power": 17,
"dig_gain": 3
},
"tx_lut_13": {
"pa_gain": 0,
"mix_gain": 10,
"rf_power": 18,
"dig_gain": 3
},
"tx_lut_14": {
"pa_gain": 0,
"mix_gain": 11,
"rf_power": 19,
"dig_gain": 3
},
"tx_lut_15": {
"pa_gain": 0,
"mix_gain": 12,
"rf_power": 20,
"dig_gain": 3
}
},
"gateway_conf": {
"gateway_ID": "XXXXXXXXXXXXXXXX",
"server_address": "router.eu.thethings.network",
"serv_port_up": 1700,
"serv_port_down": 1700,
"keepalive_interval": 10,
"stat_interval": 30,
"push_timeout_ms": 100,
"forward_crc_valid": true,
"forward_crc_error": false,
"forward_crc_disabled": false
}
}
```
To stop the Pygate at any time use:
- REPL -> use CTRL-C
- using deinit function `machine.pygate_deinit()`
that will stop GW tasks and safely power off the Concentrator.

View File

@@ -1,9 +1,9 @@
---
title: "LTE Examples"
aliases:
- chapter/tutorials/lte
---
The following tutorials demonstrate the use of the LTE CAT-M1 and NB-IoT functionality on cellular enabled Pycom modules.
Our cellular modules support both LTE CAT-M1 and NB-IoT, these are new lower power, long range, cellular protocols. These are not the same as the full version of 2G/3G/LTE supported by cell phones, and require your local carriers to support them. At the time of writing, CAT-M1 and NB-IoT connectivity is not widely available so be sure to check with local carriers if support is available where you are.

View File

@@ -0,0 +1,202 @@
# COAP
This module implements a CoAp Server and Client, it operates as both at the same time.
## Usage Example
```python
from network import WLAN
from network import Coap
import uselect
import _thread
# Callback handling the responses to the requests sent to a Coap Server
def response_callback(code, id_param, type_param, token, payload):
print("Code: {}".format(code))
# The ID can be used to pair the requests with the responses
print("ID: {}".format(id_param))
print("Type: {}".format(type_param))
print("Token: {}".format(token))
print("Payload: {}".format(payload))
# Thread handling the sockets
def socket_thread(p, coap_socket):
while True:
# Wait for any socket to become available
sockets = p.poll()
for s in sockets:
sock = s[0]
event = s[1]
if(event & uselect.POLLIN):
# Check if the socket belongs to Coap module
if(sock == coap_socket):
# Call Coap.read() which parses the incoming Coap message
Coap.read()
# Connect to the network
wlan = WLAN(mode=WLAN.STA)
wlan.connect('your-ssid', auth=(WLAN.WPA2, 'your-key'))
# Initialize Coap module
Coap.init(str(wlan.ifconfig()[0]), service_discovery=True)
# Add a resource with default value and plain text content format
r = Coap.add_resource("resource1", media_type=Coap.MEDIATYPE_TEXT_PLAIN, value="default_value")
# Add an attribute to the resource
r.add_attribute("title", "resource1")
# Add an attribute to the resource
r.add_attribute("ct", str(Coap.MEDIATYPE_TEXT_PLAIN))
# Configure the possible operations on the resource
r.callback(Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT, True)
# Add a resource without default value, XML content format and E-Tag enabled
r = Coap.add_resource("resource2", media_type=Coap.MEDIATYPE_APP_XML, etag=True)
# Configure the possible operations on the resource
r.callback(Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT | Coap.REQUEST_DELETE, True)
# Register the response handler for the requests the module initiates as a Coap Client
Coap.register_response_handler(response_callback)
# Get the UDP socket created for the Coap module
coap_server_socket = Coap.socket()
# Create a new poll object
p = uselect.poll()
# Register the Coap Module's socket to the poll
p.register(coap_server_socket, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR)
# Start a new thread which will handle the sockets of "p" poll
_thread.start_new_thread(socket_thread, (p, coap_server_socket))
# Send a request to a Coap server
id = Coap.send_request("192.168.0.234", Coap.REQUEST_GET, uri_port=5683, uri_path=".well-known/core", payload="payload", token="token1", include_options=True)
print(id)
```
## Initialization
#### Coap.init(address, *, port=5683, service_discovery=False)
Initialize the Coap module.
Arguments are:
* `address` is the address where Coap Module will handle the communication .
* `port` is the port where Coap Module will listen, if not given it is the default Coap UDP port: 5683.
* `service_discovery` is a boolean argument to enable/disable service discovery. If enabled, the Coap Module will listen on the Coap Multicast address too: 224.0.1.187. By default it is disabled.
## Module's methods
#### 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)
Creates a resource object and adds it to the Coap Module to operate as a server.
* `uri` is the full path of the resource.
* `media_type` is the media type (Coap option: Content-Format) of the resource. If not given, no defined media type is associated with the resource.
* `max_age` is the maximum time in seconds when the value of the resource is considered fresh (Coap option: Max-Age). If not given, no fresh time is associated with the resource.
* `value` is the default value of the resource. If not given it is initialized to decimal 0.
* `etag` is a boolean argument to enable/disable entity tag calculation (Coap option: ETag). By default it is turned off.
{% hint style="info" %}
Media type argument should be one of the standard defined value which are available via Coap Module's constants.
{% endhint %}
{% hint style="info" %}
Entity tag calculation is a simple counter increment between value 1-65535 with overflow but without value 0. Incremented each time the value of the resource is changed.
{% endhint %}
#### Coap.remove_resource(uri)
Removes the resource defined by `uri` argument.
* `uri` is the full path of the resource to be removed.
#### 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()
Must be called when a packet is received on the socket assigned to the Coap Module. This function parses the incoming request, composes and sends out the response if needed.
#### Coap.register_response_handler(callback)
Registers a callback function which will be called when a remote Coap Server responses to our request.
* `callback` is the callback to be registered. It must have the following arguments:
* `code` is the response code from the received message
* `id_param` is the transaction ID of the received message. This can be used to match together requests and the response for it.
* `type_param` is the type flag from the received message
* `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)
Creates and sends a request to a Coap server.
* `uri_host` is the IP address of the server, included in the message as an "URI-HOST" option
* `method` is the method to be sent to the server, can be: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`
* `uri_port` is the port of the server, included in the message as an "URI-PORT" option, by default it is 5683
* `uri_path` is the full path of the resource in the server, included in the message as an "URI-PATH" option. If nothing is given the request will not have URI-PATH option.
* `content_format` is the Content-Format option of the request, can be: `Coap.MEDIATYPE_TEXT_PLAIN`, `Coap.MEDIATYPE_APP_LINK_FORMAT`, `Coap.MEDIATYPE_APP_XML`, `Coap.MEDIATYPE_APP_OCTET_STREAM`, `Coap.MEDIATYPE_APP_RDF_XML`, `Coap.MEDIATYPE_APP_EXI`, `Coap.MEDIATYPE_APP_JSON`, `Coap.MEDIATYPE_APP_CBOR`. If nothing is given the request will not have Content-Format option.
* `payload` is the payload of the request. If nothing is given the request will not have payload.
* `token` is the token field of the request. If nothing is given the request will not have token field.
* `include_options` decides whether put any options (including the ones above) into the message or not. It can be used to send special requests to servers accepting Coap formed requests without options, e.g. to a Dish Telemetry server. By default the options are included.
## Class resource
The resource class represents a resource in the scope of the Coap Module when acting as a server. A new resource can be only 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)
Adds a new attribute to the resource. Attributes are used to explain the resource during service discovery.
* `name` is the name of the resource.
* `value` is the value of the resource.
{% hint style="info" %}
During service discovery, GET request to ".well-know/core", the attributes are returned with the belonging values.
E.g. using the "libcoap's" command line coap-client to fetch the resource from our server:
coap-client -m get coap://<Coap-Server's address>/.well-known/core
</resource2>,</resource1>;ct=0;title=resource1
{% endhint %}
#### resource.value(value)
Updates or fetches the value of the resource.
* `value` is the value to update the current value with.
If the method is called without parameter the current value is returned.
#### 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 to enable/disable the operations specified by `operation`
{% hint style="info" %}
During a GET request, only the first occurance of an ETAG or Accept option is parsed and interpreted, the others of the same type are dropped (if any).
{% endhint %}
{% hint style="info" %}
During a PUT request, only the first occurance of an If-Match option is parsed and interpreted, the others of the same type are dropped (if any).
{% endhint %}
{% hint style="danger" %}
Due to limitations of the underlying ESP-IDF/libcoap library, new resources cannot be added via PUT or POST requests.
{% endhint %}
## Constants
* Define the media type: `Coap.MEDIATYPE_TEXT_PLAIN`, `Coap.MEDIATYPE_APP_LINK_FORMAT`, `Coap.MEDIATYPE_APP_XML`, `Coap.MEDIATYPE_APP_OCTET_STREAM`, `Coap.MEDIATYPE_APP_RDF_XML`, `Coap.MEDIATYPE_APP_EXI`, `Coap.MEDIATYPE_APP_JSON`, `Coap.MEDIATYPE_APP_CBOR`
* Define the operation: `Coap.REQUEST_GET`, `Coap.REQUEST_PUT`, `Coap.REQUEST_POST`, `Coap.REQUEST_DELETE`

View File

@@ -15,7 +15,6 @@
<link rel="icon" href="/favicon.ico">
</head>
<body>
</script>
<v-app id="app" class="grey lighten-5" v-cloak stylse="display: none;">
{{ partial "menu.html" . }}
{{- partial "toolbar.html" . -}}
@@ -59,8 +58,8 @@
drawer2: true,
toc: 0,
branches: [
{ value: 'https://docs.pycom.io', text: 'version stable', },
{ value: 'https://development.pycom.io', text: 'version development'},
{ value: 'https://docs.pycom.io', text: 'version stable', },
],
branch: ""
},
@@ -103,7 +102,7 @@
fetchResults (kw, start) {
if (!start) { start = 1 }
let key = "AIzaSyCDyOKwSjrgE_tkSbO0kbI8Omc6VZMwqA8";
let cx = "000185904715529159933:pfyw5o4foii";
let cx = "000185904715529159933:irgu2wbrygm";
let url = "https://www.googleapis.com/customsearch/v1";
url = url + "?cx=" + cx + "&key=" + key + "&q=" + encodeURI(kw) + "&start=" + start

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB