mirror of
https://github.com/sascha-hemi/pycom-documentation.git
synced 2026-03-21 05:06:35 +01:00
GitBook: [development_release] 23 pages modified
This commit is contained in:
committed by
gitbook-bot
parent
a1b62c0f5e
commit
30e81743e3
@@ -74,6 +74,7 @@
|
||||
* [Modbus](tutorials/all/modbus.md)
|
||||
* [OTA update](tutorials/all/ota.md)
|
||||
* [RMT](tutorials/all/rmt.md)
|
||||
* [Socket](tutorials/all/socket.md)
|
||||
* [LoRa Examples](tutorials/lora/README.md)
|
||||
* [LoRa-MAC \(Raw LoRa\)](tutorials/lora/lora-mac.md)
|
||||
* [LoRaWAN with OTAA](tutorials/lora/lorawan-otaa.md)
|
||||
@@ -82,6 +83,7 @@
|
||||
* [LoPy to LoPy](tutorials/lora/module-module.md)
|
||||
* [LoRaWAN Nano-Gateway](tutorials/lora/lorawan-nano-gateway.md)
|
||||
* [RN2483 to LoPy](tutorials/lora/rn2483-to-lopy.md)
|
||||
* [LoRa Mesh](tutorials/lora/lora-mesh.md)
|
||||
* [Sigfox Examples](tutorials/sigfox.md)
|
||||
* [LTE Examples](tutorials/lte/README.md)
|
||||
* [CAT-M1](tutorials/lte/cat-m1.md)
|
||||
@@ -143,7 +145,8 @@
|
||||
* [uhashlib](firmwareapi/micropython/uhashlib.md)
|
||||
* [ussl](firmwareapi/micropython/ussl.md)
|
||||
* [ucrypto](firmwareapi/micropython/ucrypto.md)
|
||||
* [ustruct](firmwareapi/micropython/ustruct.md)
|
||||
* [ustruct](firmwareapi/micropython/ustruct/README.md)
|
||||
* [uzlib](firmwareapi/micropython/ustruct/uzlib.md)
|
||||
* [\_thread](firmwareapi/micropython/_thread.md)
|
||||
* [Builtin](firmwareapi/micropython/builtin.md)
|
||||
* [Notes](firmwareapi/notes.md)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Mesh Networks
|
||||
|
||||
Mesh Networking is currently under development. Please click [here](https://docs.pycom.io/v/dev/tutorials-and-examples/lora/lora-mesh) for the documentation. Please keep in mind that this document is still only informational.
|
||||
Mesh Networking is currently under development. Please click [here](../tutorials/lora/lora-mesh.md) for the documentation. Please keep in mind that this document is still only informational.
|
||||
|
||||
|
||||
@@ -87,9 +87,25 @@ uos.unmount(path)
|
||||
|
||||
Unmounts a previously mounted block device from the given path.
|
||||
|
||||
#### uos.mkfs\(block\_device or path\)
|
||||
#### uos.mkfat\(block\_device\)
|
||||
|
||||
Formats the specified path, must be either `/flash` or `/sd`. A block device can also be passed like an SD object before being mounted.
|
||||
Instantiate a VFS \(Virtual File System\) object with underlying FAT file system.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
from machine import SD
|
||||
import os
|
||||
sd = SD()
|
||||
vfs = os.mkfat(sd) # Creating a VFS
|
||||
vfs.mkfs(sd) # Formating the SD card
|
||||
# Now we can use normal os mount
|
||||
os.mount(vfs, '/sd')
|
||||
```
|
||||
|
||||
#### uos.fsformat\(path\)
|
||||
|
||||
Formats the block device mounted under the input path, must be either `/flash` or `/sd`
|
||||
|
||||
#### uos.dupterm\(stream\_object\)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ SSL sockets inherit all methods and from the standard sockets, see the `usocket`
|
||||
|
||||
## Exceptions
|
||||
|
||||
* `ssl.SSLError`
|
||||
`ssl.SSLError`
|
||||
|
||||
## Constants
|
||||
|
||||
|
||||
26
firmwareapi/micropython/ustruct/uzlib.md
Normal file
26
firmwareapi/micropython/ustruct/uzlib.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
description: zlib decompression
|
||||
---
|
||||
|
||||
# uzlib
|
||||
|
||||
_This module implements a subset of the corresponding_ `CPython` _module, as described below. For more information, refer to the original CPython documentation:_ `zlib`.
|
||||
|
||||
This module allows to decompress binary data compressed with [DEFLATE algorithm](https://en.wikipedia.org/wiki/DEFLATE) \(commonly used in zlib library and gzip archiver\). Compression is not yet implemented.
|
||||
|
||||
## **Methods**
|
||||
|
||||
**uzlib.decompress\(data, wbits=0, bufsize=0\)**
|
||||
|
||||
Return decompressed data as bytes. wbits is DEFLATE dictionary window size used during compression \(8-15, the dictionary size is power of 2 of that value\). Additionally, if value is positive, data is assumed to be zlib stream \(with zlib header\). Otherwise, if it’s negative, it’s assumed to be raw DEFLATE stream. bufsize parameter is for compatibility with CPython and is ignored.
|
||||
|
||||
**class uzlib.DecompIO\(stream, wbits=0\)**
|
||||
|
||||
Create a `stream` wrapper which allows transparent decompression of compressed data in another stream. This allows to process compressed streams with data larger than available heap size. In addition to values described in `decompress()`, wbits may take values 24..31 \(16 + 8..15\), meaning that input stream has gzip header.
|
||||
|
||||
{% hint style="info" %}
|
||||
**Difference to CPython**
|
||||
|
||||
This class is MicroPython extension. It’s included on provisional basis and may be changed considerably or removed in later versions.
|
||||
{% endhint %}
|
||||
|
||||
@@ -61,15 +61,15 @@ Just like `ticks_ms` above, but in microseconds.
|
||||
|
||||
Same as `ticks_us`, but faster.
|
||||
|
||||
#### utime.ticks\_diff\(old, new\)
|
||||
#### utime.ticks\_diff\(end, start\)
|
||||
|
||||
Measure period between consecutive calls to `ticks_ms()`, `ticks_us()`, or `ticks_cpu()`. The value returned by these functions may wrap around at any time, so directly subtracting them is not supported. `ticks_diff()` should be used instead. "old" value should actually precede "new" value in time, or result is undefined. This function should not be used to measure arbitrarily long periods of time \(because `ticks_*()` functions wrap around and usually would have short period\). The expected usage pattern is implementing event polling with timeout:
|
||||
Measure period between consecutive calls to `ticks_ms()`, `ticks_us()`, or `ticks_cpu()`. The value returned by these functions may wrap around at any time, so directly subtracting them is not supported. `ticks_diff()` should be used instead. "start" value should actually precede "end" value in time, or result is undefined. This function should not be used to measure arbitrarily long periods of time \(because `ticks_*()` functions wrap around and usually would have short period\). The expected usage pattern is implementing event polling with timeout:
|
||||
|
||||
```python
|
||||
# Wait for GPIO pin to be asserted, but at most 500us
|
||||
start = time.ticks_us()
|
||||
while pin.value() == 0:
|
||||
if time.ticks_diff(start, time.ticks_us()) > 500:
|
||||
if time.ticks_diff(time.ticks_us(), start) > 500:
|
||||
raise TimeoutError
|
||||
```
|
||||
|
||||
|
||||
@@ -42,15 +42,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:
|
||||
|
||||
|
||||
@@ -110,23 +110,19 @@ Return value: Tuple of items with the following structure: `(level, duration)`:
|
||||
Maximum of 128 pulses can be received in a row without receiving "idle" signal. If the incoming pulse sequence contains more than 128 pulses the rest is dropped and the receiver waits for another sequence of pulses. The `pulses_get` function can be called to receive more than 128 pulses, however the above mentioned limitation should be kept in mind when evaluating the received data.
|
||||
{% endhint %}
|
||||
|
||||
#### rmt.pulses\_send\(duration, data, start\_level\)
|
||||
#### rmt.pulses\_send\(duration, data, start\_level, wait\_tx\_done\)
|
||||
|
||||
Generates pulses as defined by the parameters below
|
||||
|
||||
* `duration` represents the duration of the pulses to be sent,
|
||||
|
||||
the time unit \(resolution\) depends on the selected channel.
|
||||
|
||||
* `data` Tuple that represents the sequence of pulses to be sent, must be
|
||||
|
||||
composed of 0 or 1 elements.
|
||||
|
||||
* `start_level` defines the state \(HIGH/LOW\) of the first pulse given by
|
||||
|
||||
`duration` if `data` is not given.
|
||||
|
||||
`data` must be a tuple and `duration` can be a tuple or a single number, with `data` being optional. In the case that only `duration` is provided, it must be a tuple and you must also provide `start_level` which will dictate the level of the first duration, the signal level then toggles between each duration value. If `data` is provided and `duration` is a single number, each pulse in `data` will have have an equal length as set by `duration`. If `data` and `duration` are provided as tuples, they must be of the same number of elements, with each pulse lasting its matching duration.
|
||||
* `duration` represents the duration of the pulses to be sent, the time unit \(resolution\) depends on the selected channel.
|
||||
* `data` Tuple that represents the sequence of pulses to be sent, must be composed of 0 or 1 elements.
|
||||
* `start_level` defines the state \(HIGH/LOW\) of the first pulse given by `duration` if `data` is not given.
|
||||
* `data` must be a tuple and `duration` can be a tuple or a single number, with `data` being optional. In the case that only `duration` is provided, it must be a tuple and you must also provide `start_level` which will dictate the level of the first duration, the signal level then toggles between each duration value.
|
||||
* If `data` is provided and `duration` is a single number, each pulse in `data` will have have an equal length as set by `duration`.
|
||||
* If `data` and `duration` are provided as tuples, they must be of the same number of elements, with each pulse lasting its matching duration.
|
||||
* `wait_tx_done` :
|
||||
* `False`: Allows the function to send asynchronosly without waiting for the transmission to be done.
|
||||
* `True`: will wait for transmission to be done
|
||||
|
||||
## Constants
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ rtc = RTC(id=0)
|
||||
|
||||
Initialise the RTC. The arguments are:
|
||||
|
||||
* `datetime` when passed it sets the current time. It is a tuple of the form: `(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])`
|
||||
* `datetime` when passed it sets the current time. It is a tuple of the form: `(year, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])`.
|
||||
* `source` selects the oscillator that drives the RTC. The options are RTC.INTERNAL\_RC and RTC.XTAL\_32KHZ
|
||||
|
||||
For example:
|
||||
@@ -73,6 +73,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`
|
||||
|
||||
@@ -155,9 +155,10 @@ 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`.
|
||||
* `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
|
||||
@@ -247,3 +248,7 @@ Closes the BLE connection with the client.
|
||||
* Characteristic callback events: `Bluetooth.CHAR_READ_EVENT`, `Bluetooth.CHAR_WRITE_EVENT`, `Bluetooth.NEW_ADV_EVENT`, `Bluetooth.CLIENT_CONNECTED`, `Bluetooth.CLIENT_DISCONNECTED`, `Bluetooth.CHAR_NOTIFY_EVENT`
|
||||
* Antenna type: `Bluetooth.INT_ANT`, `Bluetooth.EXT_ANT`
|
||||
|
||||
## Exceptions
|
||||
|
||||
* `Bluetooth.timeout`
|
||||
|
||||
|
||||
@@ -42,3 +42,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))))
|
||||
```
|
||||
|
||||
|
||||
@@ -371,6 +371,34 @@ Remove the LoRaWAN state \(joined status, network keys, packet counters, etc\) f
|
||||
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\(\)
|
||||
|
||||
Enable the Mesh network. Only after Mesh enabling the `lora.cli()` and `socket` can be used.
|
||||
|
||||
```python
|
||||
lora.mesh()
|
||||
```
|
||||
|
||||
#### lora.cli\(\)
|
||||
|
||||
Send OpenThread CLI commands, the list is [here](https://github.com/openthread/openthread/blob/master/src/cli/README.md). The output is multiline string, having as line-endings the `\r\n`.
|
||||
|
||||
```bash
|
||||
>>> print(lora.cli("ipaddr"))
|
||||
fdde:ad00:beef:0:0:ff:fe00:fc00
|
||||
fdde:ad00:beef:0:0:ff:fe00:e800
|
||||
fdde:ad00:beef:0:e1f0:783c:1e8f:c763
|
||||
fe80:0:0:0:2c97:cb65:3219:c86
|
||||
```
|
||||
|
||||
## Constants
|
||||
|
||||
* LoRa stack mode: `LoRa.LORA`, `LoRa.LORAWAN`
|
||||
@@ -382,6 +410,10 @@ lora.nvram_erase()
|
||||
* LoRaWAN device class: `LoRa.CLASS_A`, `LoRa.CLASS_C`
|
||||
* LoRaWAN regions: `LoRa.AS923`, `LoRa.AU915`, `LoRa.EU868`, `LoRa.US915`
|
||||
|
||||
## Exceptions
|
||||
|
||||
* `LoRa.timeout`
|
||||
|
||||
## Working with LoRa and LoRaWAN Sockets
|
||||
|
||||
LoRa sockets are created in the following way:
|
||||
@@ -393,6 +425,12 @@ s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
|
||||
|
||||
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()`.
|
||||
{% endhint %}
|
||||
|
||||
LoRa sockets support the following standard methods from the socket module:
|
||||
|
||||
#### socket.close\(\)
|
||||
@@ -429,6 +467,16 @@ or
|
||||
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:
|
||||
|
||||
@@ -44,7 +44,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\)
|
||||
|
||||
Set or get the WiFi network processor configuration.
|
||||
|
||||
@@ -61,6 +61,7 @@ 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`
|
||||
|
||||
For example, you can do:
|
||||
|
||||
@@ -80,7 +81,7 @@ wlan.init(mode=WLAN.STA)
|
||||
|
||||
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.
|
||||
|
||||
@@ -93,6 +94,7 @@ 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.
|
||||
@@ -148,9 +150,18 @@ Get or set the antenna type \(external or internal\).
|
||||
|
||||
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
|
||||
|
||||
## 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`
|
||||
|
||||
|
||||
@@ -151,3 +151,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.
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ Please ensure you have the signal level of the UART adapter set to `3.3v` before
|
||||
{% endhint %}
|
||||
|
||||
* In order to put the GPy into bootloader mode to update the device firmware you will need to connect `P2` to `GND`. We recommend you connect a button between the two to make this simpler.
|
||||
|
||||

|
||||
{% endtab %}
|
||||
|
||||
{% tab title="WiFi" %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# LoPy
|
||||
|
||||
## Basic connection
|
||||
## Basic connection {#basic-connection}
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Exp Board 2.0" %}
|
||||
@@ -8,30 +8,32 @@
|
||||
* Locate the USB connector on the expansion board.
|
||||
* Insert the LoPy module on the the expansion board with the reset button pointing towards the USB connector. It should firmly click into place and the pins should now no longer be visible.
|
||||
|
||||

|
||||

|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Exp Board 3.0" %}
|
||||
* Before connecting your module to an Expansion Board 3.0, you should update the firmware on the Expansion Board 3.0. Instructions on how to do this can be found [here](../../pytrackpysense/installation/firmware.md).
|
||||
* Before connecting your module to an Expansion Board 3.0, you should update the firmware on the Expansion Board 3.0. Instructions on how to do this can be found [here](https://pycom.gitbook.io/dan-sbook/pytrack-pysense-pyscan/installation/firmware).
|
||||
* Look for the reset button on the module \(located at a corner of the board, next to the LED\).
|
||||
* Locate the USB connector on the expansion board.
|
||||
* Insert the LoPy module on the Expansion Board with the reset button pointing towards the USB connector. It should firmly click into place and the pins should now no longer be visible.
|
||||
|
||||

|
||||

|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Pytrack/Pysense/Pyscan" %}
|
||||
* Before connecting your module to a Pysense/Pytrack/Pyscan board, you should update the firmware on the Pysense/Pytrack/Pyscan. Instructions on how to do this can be found [here](../../pytrackpysense/installation/firmware.md).
|
||||
* Before connecting your module to a Pysense/Pytrack/Pyscan board, you should update the firmware on the Pysense/Pytrack/Pyscan. Instructions on how to do this can be found [here](https://pycom.gitbook.io/dan-sbook/pytrack-pysense-pyscan/installation/firmware).
|
||||
* Look for the reset button on the LoPy module \(located at a corner of the board, next to the LED\).
|
||||
* Locate the USB connector on the Pysense/Pytrack/Pyscan.
|
||||
* Insert the module on the Pysense/Pytrack/Pyscan with the reset button pointing towards the USB connector. It should firmly click into place and the pins should now no longer be visible. 
|
||||
* Insert the module on the Pysense/Pytrack/Pyscan with the reset button pointing towards the USB connector. It should firmly click into place and the pins should now no longer be visible.
|
||||
|
||||

|
||||
{% endtab %}
|
||||
|
||||
{% tab title="USB UART Adapter" %}
|
||||
* Firstly you will need to connect power to your LoPy. You will need to supply `3.5v`-`5.5v` to the `Vin` pin.
|
||||
|
||||
{% hint style="danger" %}
|
||||
Do _not_ feed `3.3v` directly to the `3.3v` supply pin, this will damage the regulator.
|
||||
Do **not** feed `3.3v` directly to the `3.3v` supply pin, this will damage the regulator.
|
||||
{% endhint %}
|
||||
|
||||
* The connect the `RX` and `TX` of your USB UART to the `TX` and `RX` of the LoPy respectively.
|
||||
@@ -42,7 +44,7 @@ Please ensure you have the signal level of the UART adapter set to `3.3v` before
|
||||
|
||||
* In order to put the LoPy into bootloader mode to update the device firmware you will need to connect `P2` to `GND`. We recommend you connect a button between the two to make this simpler.
|
||||
|
||||

|
||||

|
||||
{% endtab %}
|
||||
|
||||
{% tab title="WiFi" %}
|
||||
@@ -50,7 +52,7 @@ Please ensure you have the signal level of the UART adapter set to `3.3v` before
|
||||
|
||||
* In order to access the LoPy via WiFi you only need to provide `3.5v` - `5.5v` on the `Vin` pin of the LoPy:
|
||||
|
||||

|
||||

|
||||
|
||||
* By default, when the LoPy boots, it will create a WiFi access point with the following credentials:
|
||||
* SSID: `lopy-wlan`
|
||||
|
||||
@@ -22,7 +22,7 @@ If you are using Atom, it is important to check at this point that Atom has succ
|
||||
If this is not the case you can press `alt-ctrl-r` on Windows/Linux or `ctrl-alt-cmd-l` on macOS, in order to reload Atom and fix the issue.
|
||||
{% endhint %}
|
||||
|
||||
4. Now that you have a project created, we need to add some files to it. A standard MicroPython project has the following structure:
|
||||
1. Now that you have a project created, we need to add some files to it. A standard MicroPython project has the following structure:
|
||||
|
||||
```text
|
||||
RGB-Blink
|
||||
|
||||
@@ -30,7 +30,7 @@ Install the Firmware updater on your computer.
|
||||
|
||||

|
||||
|
||||
2. Select your device serial port \(Make sure your device is connected to your computer\);
|
||||
2 .Select your device serial port \(Make sure your device is connected to your computer\);
|
||||
|
||||
3. Mark the options "Erase flash file system" and "Force update Pybytes registration";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ In this section, we will explain to you how to create widgets for data visualisa
|
||||
We assume that you already have your device connected to Pybytes. In case you haven't, check how to [add your device here](connect/). After your done with that, you can proceed to the next example.
|
||||
{% endhint %}
|
||||
|
||||
## Step 1: Set up your application \(`main.py`\)
|
||||
## Step 1: Set up your application \(main.py\)
|
||||
|
||||
The first step is to have an application running on your device. The application in this example sends data from a vector every 10 seconds to Pybytes.
|
||||
|
||||
|
||||
137
tutorials/all/socket.md
Normal file
137
tutorials/all/socket.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# Socket
|
||||
|
||||
Detailed information about this class can be found in [usocket](../../firmwareapi/micropython/usocket.md).
|
||||
|
||||
### Setting up a server with blocking sockets
|
||||
|
||||
The following example sets up a server which can accept 5 connections in parallel, create a new thread for each connected client, receives and sends back data then close the socket.
|
||||
|
||||
```python
|
||||
import usocket
|
||||
import _thread
|
||||
import time
|
||||
|
||||
# Thread for handling a client
|
||||
def client_thread(clientsocket,n):
|
||||
# Receive maxium of 12 bytes from the client
|
||||
r = clientsocket.recv(12)
|
||||
|
||||
# If recv() returns with 0 the other end closed the connection
|
||||
if len(r) == 0:
|
||||
clientsocket.close()
|
||||
return
|
||||
else:
|
||||
# Do something wth the received data...
|
||||
print("Received: {}".format(str(r)))
|
||||
|
||||
# Sends back some data
|
||||
clientsocket.send(str(n))
|
||||
|
||||
# Close the socket and terminate the thread
|
||||
clientsocket.close()
|
||||
|
||||
# Set up server socket
|
||||
serversocket = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
|
||||
serversocket.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
|
||||
serversocket.bind(("192.168.0.249", 6543))
|
||||
|
||||
# Accept maximum of 5 connections at the same time
|
||||
serversocket.listen(5)
|
||||
|
||||
# Unique data to send back
|
||||
c = 0
|
||||
while True:
|
||||
# Accept the connection of the clients
|
||||
(clientsocket, address) = serversocket.accept()
|
||||
# Start a new thread to handle the client
|
||||
_thread.start_new_thread(client_thread, (clientsocket, c))
|
||||
c = c+1
|
||||
```
|
||||
|
||||
The following example sets up a client which can connect to a server with 2 non-blocking sockets, create a new thread to handle the non-blocking sockets.
|
||||
|
||||
```python
|
||||
import socket
|
||||
import _thread
|
||||
import time
|
||||
import uerrno
|
||||
import uselect
|
||||
|
||||
def socket_thread(p):
|
||||
|
||||
while True:
|
||||
# Wait for any action to happen infinitely
|
||||
l = p.poll()
|
||||
|
||||
# Start processing the actions happened
|
||||
for t in l:
|
||||
# First element of the returned tuple is the socket itself
|
||||
sock = t[0]
|
||||
# Second element of the returned tuple is the events happened
|
||||
event = t[1]
|
||||
|
||||
# If any error or connection drop happened close the socket
|
||||
if(event & uselect.POLLERR or event & uselect.POLLHUP):
|
||||
sock.close()
|
||||
continue
|
||||
|
||||
# If the socket is writable then send some data
|
||||
# The socket becomes writable if the connect() was successfull
|
||||
if(event & uselect.POLLOUT):
|
||||
# If any error occurs during sending here, do "nothing", poll() will return with error event, close the socket there
|
||||
try:
|
||||
sock.send("Data to send")
|
||||
# We only want to send one message on this socket, in the future wait only for new incoming messages
|
||||
p.modify(sock, uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# If any new data is received then get it
|
||||
if(event & uselect.POLLIN):
|
||||
# If any error occurs during receiving here, do "nothing", poll() will return with error event, close the socket there
|
||||
try:
|
||||
r = sock.recv(1)
|
||||
# If recv() returns with 0 the other end closed the connection
|
||||
if len(r) == 0:
|
||||
sock.close()
|
||||
continue
|
||||
else:
|
||||
# Do something with the received data...
|
||||
print("Data received: " + str(r))
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# List for storing our sockets
|
||||
socket_list = []
|
||||
|
||||
# Set up the first socket in non-blocking mode
|
||||
s1 = socket.socket()
|
||||
s1.setblocking(False)
|
||||
socket_list.append(s1)
|
||||
# Set up the second socket in non-blocking mode
|
||||
s2 = socket.socket()
|
||||
s2.setblocking(False)
|
||||
socket_list.append(s2)
|
||||
|
||||
# Create a new poll object
|
||||
p = uselect.poll()
|
||||
# Register the sockets into the poll object, wait for all kind of events
|
||||
p.register(s1, uselect.POLLIN | uselect.POLLOUT | uselect.POLLHUP | uselect.POLLERR)
|
||||
p.register(s2, uselect.POLLIN | uselect.POLLOUT | uselect.POLLHUP | uselect.POLLERR)
|
||||
|
||||
# Try to connect to the server with each sockets
|
||||
for s in socket_list:
|
||||
try:
|
||||
s.connect(socket.getaddrinfo("192.168.0.234", 6543)[0][-1])
|
||||
except OSError as e:
|
||||
# In case of non-blocking socket the connect() raises eception of EINPROGRESS what is expected
|
||||
if e.args[0] != uerrno.EINPROGRESS:
|
||||
# Raise all other errors
|
||||
raise
|
||||
|
||||
# Start the thread which takes care of the non-blocking sockets through the created poll object
|
||||
_thread.start_new_thread(socket_thread, (p,))
|
||||
```
|
||||
|
||||
125
tutorials/lora/lora-mesh.md
Normal file
125
tutorials/lora/lora-mesh.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# LoRa Mesh
|
||||
|
||||
The LoRa Mesh is implemented using [OpenThread](https://openthread.io/guides/thread-primer).
|
||||
|
||||
To understand the OpenThread terms and overall functionality, these guides are highly recommended:
|
||||
|
||||
* [What is Thread?](https://openthread.io/guides/thread-primer)
|
||||
* [Node Roles and Types](https://openthread.io/guides/thread-primer/node-roles-and-types)
|
||||
* [IPv6 Addressing](https://openthread.io/guides/thread-primer/ipv6-addressing) \(especially, RLOC unicast address\)
|
||||
|
||||
Important, all the OpenThread CLI commands are accessible using `LoRa.cli("command")`, the complete list of commands is [here](https://github.com/openthread/openthread/blob/master/src/cli/README.md). Please note some commands, can't execute, as some functionalities are not implemented \(ex: Commissioning Role, Joiner Role, DNS\).
|
||||
|
||||
This example shows how to:
|
||||
|
||||
* enable LoRa-Mesh network
|
||||
* find neighbors \(parent, children, other router direct connections\)
|
||||
* send PING to neighbors
|
||||
* open UDP socket for:
|
||||
* listening incoming UDP packets and answering back \(ACK\)
|
||||
* sending packets to all neighbors
|
||||
* toggle LED as packet/ping is received.
|
||||
|
||||
{% hint style="info" %}
|
||||
The LoRa-Mesh socket supports only the following socket methods: `close()`, `bind()`, `sendto()`, and `recvfrom()`.
|
||||
{% endhint %}
|
||||
|
||||
**Lora Mesh example**
|
||||
|
||||
* Source: [https://github.com/pycom/pycom-libraries/blob/master/lib/lora\_mesh/main.py](https://github.com/pycom/pycom-libraries/blob/master/lib/lora_mesh/main.py)
|
||||
* `Loramesh` micropython library is available at [https://github.com/pycom/pycom-libraries/blob/master/lib/lora\_mesh/loramesh.py](https://github.com/pycom/pycom-libraries/blob/master/lib/lora_mesh/loramesh.py).
|
||||
|
||||
```python
|
||||
from network import LoRa
|
||||
import socket
|
||||
import time
|
||||
import utime
|
||||
import ubinascii
|
||||
import pycom
|
||||
import machine
|
||||
|
||||
from loramesh import Loramesh
|
||||
|
||||
lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868, bandwidth=LoRa.BW_125KHZ, sf=7)
|
||||
MAC = str(ubinascii.hexlify(lora.mac()))[2:-1]
|
||||
print("LoRa MAC: %s"%MAC)
|
||||
|
||||
mesh = Loramesh(lora)
|
||||
|
||||
# waiting until it connected to Mesh network and
|
||||
# it has some valid neighbors
|
||||
while True:
|
||||
mesh.led_state()
|
||||
print("%d: State %s, single %s"%(time.time(), mesh.cli('state'), mesh.cli('singleton')))
|
||||
time.sleep(2)
|
||||
if not mesh.is_connected():
|
||||
continue
|
||||
|
||||
neigbors = mesh.neighbors_ip()
|
||||
if len(neigbors) == 0:
|
||||
print('No neighbor')
|
||||
continue
|
||||
|
||||
print('Neighbors found: %s'%neigbors)
|
||||
break
|
||||
|
||||
# create UDP socket
|
||||
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
|
||||
myport = 1234
|
||||
s.bind(myport)
|
||||
pack_num = 1
|
||||
msg = "Hello World! MAC: " + MAC + ", pack: "
|
||||
ip = mesh.ip()
|
||||
|
||||
while True:
|
||||
mesh.led_state()
|
||||
print("%d: State %s, single %s, IP %s"%(time.time(), mesh.cli('state'), mesh.cli('singleton'), mesh.ip()))
|
||||
|
||||
# check if topology changes, maybe RLOC IPv6 changed
|
||||
new_ip = mesh.ip()
|
||||
if ip != new_ip:
|
||||
print("IP changed from: %s to %s"%(ip, new_ip))
|
||||
ip = new_ip
|
||||
|
||||
# listen for incomming packets
|
||||
rcv_data, rcv_addr = s.recvfrom(128)
|
||||
if len(rcv_data)>0:
|
||||
rcv_ip = rcv_addr[0]
|
||||
rcv_port = rcv_addr[1]
|
||||
print('Incomming %d bytes from %s (port %d)'%(len(rcv_data), rcv_ip, rcv_port))
|
||||
print(rcv_data)
|
||||
# could send some ACK pack:
|
||||
if rcv_data.startswith("Hello"):
|
||||
try:
|
||||
s.sendto('ACK ' + MAC + ' ' + str(rcv_data)[2:-1], (rcv_ip, rcv_port))
|
||||
except Exception:
|
||||
pass
|
||||
mesh.blink(7, .3)
|
||||
continue
|
||||
|
||||
# update neighbors list
|
||||
neigbors = mesh.neighbors_ip()
|
||||
print("%d Neighbors %s"%(len(neigbors), neigbors))
|
||||
|
||||
# send PING and UDP packets to all neighbors
|
||||
for neighbor in neigbors:
|
||||
if mesh.ping(neighbor) > 0:
|
||||
print('Ping OK from neighbor %s'%neighbor)
|
||||
mesh.blink(10, .1)
|
||||
else:
|
||||
print('Ping not received from neighbor %s'%neighbor)
|
||||
|
||||
time.sleep(10)
|
||||
|
||||
pack_num = pack_num + 1
|
||||
try:
|
||||
s.sendto(msg + str(pack_num), (neighbor, myport))
|
||||
print('Sent message to %s'%(neighbor))
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(20 + machine.rng()%20)
|
||||
|
||||
# random sleep time
|
||||
time.sleep(30 + machine.rng()%30)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user