GitBook: [development_release] 23 pages modified

This commit is contained in:
Daniel Spindelbauer
2018-08-24 07:54:50 +00:00
committed by gitbook-bot
parent a1b62c0f5e
commit 30e81743e3
22 changed files with 473 additions and 41 deletions

View File

@@ -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)

View File

@@ -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.

View File

@@ -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\)

View File

@@ -32,7 +32,7 @@ SSL sockets inherit all methods and from the standard sockets, see the `usocket`
## Exceptions
* `ssl.SSLError`
`ssl.SSLError`
## Constants

View 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 its negative, its 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. Its included on provisional basis and may be changed considerably or removed in later versions.
{% endhint %}

View File

@@ -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
```

View File

@@ -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:

View File

@@ -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

View File

@@ -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`

View File

@@ -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`

View File

@@ -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))))
```

View File

@@ -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:

View File

@@ -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`

View File

@@ -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.

View File

@@ -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.
![](../../.gitbook/assets/uart_gpy.png)
{% endtab %}
{% tab title="WiFi" %}

View File

@@ -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.
![](../../.gitbook/assets/expansion_board_2_lopy.png)
![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_D1o1RiKJjzcBlfJ%2FExpansion_Board_2_LoPy.png?generation=1534772069584204&alt=media)
{% 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.
![](../../.gitbook/assets/expansion_board_3_lopy.png)
![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_UweAMmh-NueZ_dX%2FExpansion_Board_3_LoPy.png?generation=1534772081040942&alt=media)
{% 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. ![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_ZvQtB3k9-QzXSEi%2FPysense_LoPy.png?generation=1534772084691543&alt=media)![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_aBQabbigN5pR8W2%2FPytrack_LoPy.png?generation=1534772068406423&alt=media)
* 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.
![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_ZvQtB3k9-QzXSEi%2FPysense_LoPy.png?generation=1534772084691543&alt=media)![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_aBQabbigN5pR8W2%2FPytrack_LoPy.png?generation=1534772068406423&alt=media)
{% 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.
![](../../.gitbook/assets/uart_lopy.png)
![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIq_kogUb61sVzFipSE%2FUART_LoPy.png?generation=1534772074950525&alt=media)
{% 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:
![](../../.gitbook/assets/bare_lopy.png)
![](https://blobscdn.gitbook.com/v0/b/gitbook-28427.appspot.com/o/assets%2F-LIfiUlGe6_zTmmvcuEa%2F-LKMXk1KQvBgjpw04I3u%2F-LIqa1aumXwEUaXR6jHk%2FBare_LoPy.png?generation=1534772083120637&alt=media)
* By default, when the LoPy boots, it will create a WiFi access point with the following credentials:
* SSID: `lopy-wlan`

View File

@@ -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

View File

@@ -30,7 +30,7 @@ Install the Firmware updater on your computer.
![](../../.gitbook/assets/2%20%281%29.png)
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";

View File

@@ -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
View 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
View 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)
```