diff --git a/content/firmwareapi/pycom/machine/_index.md b/content/firmwareapi/pycom/machine/_index.md index 3e3321a..f3489d0 100644 --- a/content/firmwareapi/pycom/machine/_index.md +++ b/content/firmwareapi/pycom/machine/_index.md @@ -118,7 +118,11 @@ Returns a byte string with a unique identifier of a board/SoC. It will vary from ### 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/pygate.md b/content/firmwareapi/pycom/machine/pygate.md index c961b11..da83178 100644 --- a/content/firmwareapi/pycom/machine/pygate.md +++ b/content/firmwareapi/pycom/machine/pygate.md @@ -10,17 +10,17 @@ The Pygate is an 8-channel LoRaWAN gateway. Connect a WiPy, Gpy or LoPy4 board t ## Methods -#### machine.pygate\_init(buff) +### machine.pygate_init(buff) This function is used to initialize the Pygate - `buff`: 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.callback(trigger, [handler=None, arg=None]) - `trigger`: A trigger event(s) for invoking the callback function `handler`, the triggers/events are: @@ -34,6 +34,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 a131f38..6b32881 100644 --- a/content/firmwareapi/pycom/machine/rtc.md +++ b/content/firmwareapi/pycom/machine/rtc.md @@ -26,67 +26,57 @@ print(rtc.now()) Create an RTC object. See init for parameters of initialisation. ```python - # id of the RTC may be set if multiple are connected. Defaults to id = 0. rtc = RTC(id=0) ``` ## 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)) ``` ->`tzinfo` is ignored by this method. Use `time.timezone` to achieve similar results. +> `tzinfo` is ignored by this method. Use `time.timezone` to achieve similar results. -### rtc.ntp_sync(server, [update_period=3600]) +### rtc.ntp_sync(server, [update_period=3600, backup_server]) 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.now() -Get get the current `datetime` tuple: +Get get the current `datetime` tuple as `(year, month, day, hour, minute, second, usecond, None)` -```python - -# returns datetime tuple -rtc.now() -``` ### rtc.synced() -Returns `True` if the last `ntp_sync` has been completed, `False` otherwise: - -```python - -rtc.synced() -``` +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 +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 bc756a3..b69965b 100644 --- a/content/firmwareapi/pycom/machine/sd.md +++ b/content/firmwareapi/pycom/machine/sd.md @@ -39,7 +39,7 @@ f.close() ## Constructors -### class machine.SD(id, ...) +### class machine.SD([id]) Create a SD card object. See `sd.init()` for parameters. @@ -47,7 +47,9 @@ Create a SD card object. See `sd.init()` for parameters. ### sd.init([id=0]) -Enable the SD card. +Enable the SD card. The id is always 0. + +> Use the [os](/firmwareapi/micropython/uos/) module to manipulate files. ### sd.deinit() diff --git a/content/firmwareapi/pycom/machine/timer.md b/content/firmwareapi/pycom/machine/timer.md index 37b5c1f..1fa8348 100644 --- a/content/firmwareapi/pycom/machine/timer.md +++ b/content/firmwareapi/pycom/machine/timer.md @@ -97,7 +97,7 @@ Used to get interrupted after a specific interval. ## 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. diff --git a/content/firmwareapi/pycom/machine/touch.md b/content/firmwareapi/pycom/machine/touch.md new file mode 100644 index 0000000..d1bf2f1 --- /dev/null +++ b/content/firmwareapi/pycom/machine/touch.md @@ -0,0 +1,35 @@ +--- +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 touch inputs. + +## 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 ce7bc79..a9ecbae 100644 --- a/content/firmwareapi/pycom/machine/uart.md +++ b/content/firmwareapi/pycom/machine/uart.md @@ -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: 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..3928631 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,20 @@ 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\]) - -With no parameters given, this returns a 4-tuple of (ip, subnet mask, gateway, DNS server). +### eth.ifconfig(config=['dhcp' / configtuple]) 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..18ee4a9 100644 --- a/content/firmwareapi/pycom/network/lora/_index.md +++ b/content/firmwareapi/pycom/network/lora/_index.md @@ -5,56 +5,15 @@ aliases: --- 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 +> 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 other complete LoRa examples, check [here](/tutorials/networks/lora/) for examples. ## Constructors -#### class network.LoRa(id=0, ...) +### class network.LoRa(...) Create and configure a LoRa object. See init for params of configuration. @@ -64,17 +23,30 @@ 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.CN779` + * `LoRa.IN865` + * `LoRa.RU864` + * `LoRa.KR920` + + > If no region is provided, it will default to the setting provided in the CONFIG partition. +* `frequency` accepts values within the selected Region frequency bands. +* `tx_power` is the transmit power in dBm. +* `bandwidth` is the channel bandwidth in KHz. * `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`. @@ -86,177 +58,54 @@ The arguments are: * `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 %}} +> 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) -``` - -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: +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. + * 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. -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.coding_rate([coding_rate]) -Example: +Get or set the coding rate in raw LoRa mode (`LoRa.LORA`). The allowed values are: +* `LoRa.CODING_4_5` +* `LoRa.CODING_4_6` +* `LoRa.CODING_4_7` +* `LoRa.CODING_4_8` -```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) +### lora.preamble([preamble]) -# create an OTAA authentication parameters -app_eui = ubinascii.unhexlify('ADA4DAE3AC12676B') -app_key = ubinascii.unhexlify('11B0282A189B75B0B4D2D8C7FA38548B') +Get or set the number of preamble symbols in raw LoRa mode (`LoRa.LORA`). -# 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\]) +### 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 +119,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 +134,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 +148,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 +169,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 +181,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 +198,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 +206,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 +259,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..cc6c565 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/lte/). -{{% 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) @@ -42,7 +35,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,154 +47,113 @@ lte = LTE() ## Methods -#### lte.init(\*, carrier=None) +### lte.init([carrier=standard]) -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. 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: +* `'at&t'` +* `'verizon'` +* `'standard'` -#### lte.deinit(detach=True, reset = False) + +### 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.attach(\*, band=None, apn=None, cid=None, type=LTE.IP, legacyattach=True) +### 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 diff --git a/content/tutorials/networks/wlan.md b/content/tutorials/networks/wlan.md index 177869c..6c7e57c 100644 --- a/content/tutorials/networks/wlan.md +++ b/content/tutorials/networks/wlan.md @@ -21,9 +21,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/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;