mirror of
https://github.com/sascha-hemi/pycom-documentation.git
synced 2026-03-21 07:06:20 +01:00
Pygate (#274)
This commit is contained in:
22
content/tutorials/all/PoE.md
Normal file
22
content/tutorials/all/PoE.md
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: "PoE"
|
||||
aliases:
|
||||
- tutorials/all/PoE.html
|
||||
- tutorials/all/PoE.md
|
||||
- chapter/tutorials/all/PoE
|
||||
---
|
||||
|
||||
The PyEthernet module has onboard Power over Ethernet (PoE) power supply. This means that you can power your hardware with only an ethernet cable coming from a power injector. However, since the PoE is non-isolated, you must adhere to the following warning!
|
||||
|
||||
WARNING:
|
||||
|
||||
PoE power supply of PyEthernet module has no galvanic isolation. This means, that in accordance with
|
||||
IEEE 802.3-2005 standard you must make sure that when powered from PoE power injector there are no other external connections to any part of the module or other hardware where it is installed. Such as USB cable, serial to USB bridge, logic analyser, an oscilloscope, etc.
|
||||
|
||||
As in certain hardware configurations it can lead to unrecoverable damage of not only the PyEthernet module but all hardware connected to it.
|
||||
|
||||
Be aware - violation of that requirement voids Pycom warranty.
|
||||
|
||||
The use of battery with PoE is allowed.
|
||||
|
||||

|
||||
278
content/tutorials/all/PyGate.md
Normal file
278
content/tutorials/all/PyGate.md
Normal file
@@ -0,0 +1,278 @@
|
||||
## Pygate
|
||||
|
||||
The Pygate is an 8-channel LoRaWAN gateway. This page will help you get started with it.
|
||||
|
||||
The Pygate board can have an PyEthernet adapter connected which allows an ethernet connection. The PyEthernet also support PoE. Do check the separate [page and warning for PoE-NI!](/tutorials/all/poe)
|
||||
|
||||
### Quickstart
|
||||
|
||||
To connect your Pygate to a LoRa server, follow these steps:
|
||||
|
||||
1. Attach a WiPy, GPy or LoPy4 to the Pygate. The RGB LED of the development board should be aligned with the USB port of the Pygate.
|
||||
1. Attach the LoRa Antenna to the Pygate.
|
||||
1. Flash the Pycom Device with with a firmware build where Pygate functionality is enabled.
|
||||
1. Create a `config.json` for your Pygate and upload it.
|
||||
1. Create a `main.py` that creates an uplink (wifi, ethernet or lte) and runs the LoRa packet fowarder.
|
||||
1. Run the `main.py`.
|
||||
1. Now it is operational. The communication from other LoRa nodes such as a LoPy4 will now reach the gateway and will receive up and downlink via the PyGate.
|
||||
1. To stop the Pygate at any time press Ctrl-C on the REPL and run `machine.pygate_deinit()`. It will take a few seconds to stop the gateway tasks and safely power-off the concentrator.
|
||||
|
||||
|
||||
Make sure you supply a config matching your region (EU868, US915, etc), e.g. https://github.com/Lora-net/packet_forwarder/tree/master/lora_pkt_fwd/cfg. If you are in EU region, it should be sufficent to update the example below with your GW ID, the LoRa server address and port number.
|
||||
|
||||
|
||||
### Example TTN Wifi
|
||||
|
||||
The following example shows the script and json file to run the Pygate over Wifi connecting to [The Things Network](https://www.thethingsnetwork.org/).
|
||||
|
||||
1. log in to https://console.thethingsnetwork.org/
|
||||
1. go to Gateways and register a new gateway
|
||||
1. select "I'm using a legacy packet forwarder"
|
||||
1. make up a EUI (8 byte hexadecimal value) and register it on the TTN website
|
||||
1. enter the EUI in your `config.json` under `gateway_ID` (Just enter the hex digits without the "eui-" prefix and without spaces)
|
||||
1. select your Frequency Plan
|
||||
1. select a router - also enter the hostname in your `config.json` under `server_address`
|
||||
1. enter your wifi SSID and password in `main.py`
|
||||
1. upload `config.json` and `main.py` and reset the board
|
||||
1. you will see how it creates the uplink connection and then start the LoRa GW. It will print out some debug information while it is running. After some initialization it will print "LoRa GW started" and the LED will turn green.
|
||||
|
||||
|
||||
|
||||
```python
|
||||
from network import WLAN
|
||||
import time
|
||||
import machine
|
||||
from machine import RTC
|
||||
import pycom
|
||||
|
||||
# Disable Hearbeat
|
||||
pycom.heartbeat(False)
|
||||
|
||||
# Define callback function for Pygate events
|
||||
def machine_cb (arg):
|
||||
evt = machine.events()
|
||||
if (evt & machine.PYGATE_START_EVT):
|
||||
# Green
|
||||
pycom.rgbled(0x103300)
|
||||
elif (evt & machine.PYGATE_ERROR_EVT):
|
||||
# Red
|
||||
pycom.rgbled(0x331000)
|
||||
elif (evt & machine.PYGATE_STOP_EVT):
|
||||
# RGB off
|
||||
pycom.rgbled(0x000000)
|
||||
|
||||
# register callback function
|
||||
machine.callback(trigger = (machine.PYGATE_START_EVT | machine.PYGATE_STOP_EVT | machine.PYGATE_ERROR_EVT), handler=machine_cb)
|
||||
|
||||
# Connect to a Wifi Network
|
||||
wlan = WLAN(mode=WLAN.STA)
|
||||
wlan.connect(ssid='<SSID>', auth=(WLAN.WPA2, "<PASSWORD>"))
|
||||
|
||||
while not wlan.isconnected():
|
||||
time.sleep(1)
|
||||
|
||||
print("Wifi Connection established")
|
||||
|
||||
# Sync time via NTP server for GW timestamps on Events
|
||||
rtc = RTC()
|
||||
rtc.ntp_sync(server="0.pool.ntp.org")
|
||||
|
||||
# Read the GW config file from Filesystem
|
||||
fp = open('/flash/config.json','r')
|
||||
buf = fp.read()
|
||||
|
||||
# Start the Pygate
|
||||
machine.pygate_init(buf)
|
||||
|
||||
```
|
||||
|
||||
A sample `config.json` file for gateway configuration in EU868 region:
|
||||
|
||||
```json
|
||||
{
|
||||
"SX1301_conf": {
|
||||
"lorawan_public": true,
|
||||
"clksrc": 1,
|
||||
"antenna_gain": 0,
|
||||
"radio_0": {
|
||||
"enable": true,
|
||||
"type": "SX1257",
|
||||
"freq": 867500000,
|
||||
"rssi_offset": -164.0,
|
||||
"tx_enable": true,
|
||||
"tx_freq_min": 863000000,
|
||||
"tx_freq_max": 870000000
|
||||
},
|
||||
"radio_1": {
|
||||
"enable": true,
|
||||
"type": "SX1257",
|
||||
"freq": 868500000,
|
||||
"rssi_offset": -164.0,
|
||||
"tx_enable": false
|
||||
},
|
||||
"chan_multiSF_0": {
|
||||
"enable": true,
|
||||
"radio": 1,
|
||||
"if": -400000
|
||||
},
|
||||
"chan_multiSF_1": {
|
||||
"enable": true,
|
||||
"radio": 1,
|
||||
"if": -200000
|
||||
},
|
||||
"chan_multiSF_2": {
|
||||
"enable": true,
|
||||
"radio": 1,
|
||||
"if": 0
|
||||
},
|
||||
"chan_multiSF_3": {
|
||||
"enable": true,
|
||||
"radio": 0,
|
||||
"if": -400000
|
||||
},
|
||||
"chan_multiSF_4": {
|
||||
"enable": true,
|
||||
"radio": 0,
|
||||
"if": -200000
|
||||
},
|
||||
"chan_multiSF_5": {
|
||||
"enable": true,
|
||||
"radio": 0,
|
||||
"if": 0
|
||||
},
|
||||
"chan_multiSF_6": {
|
||||
"enable": true,
|
||||
"radio": 0,
|
||||
"if": 200000
|
||||
},
|
||||
"chan_multiSF_7": {
|
||||
"enable": true,
|
||||
"radio": 0,
|
||||
"if": 400000
|
||||
},
|
||||
"chan_Lora_std": {
|
||||
"enable": true,
|
||||
"radio": 1,
|
||||
"if": -200000,
|
||||
"bandwidth": 250000,
|
||||
"spread_factor": 7
|
||||
},
|
||||
"chan_FSK": {
|
||||
"enable": true,
|
||||
"radio": 1,
|
||||
"if": 300000,
|
||||
"bandwidth": 125000,
|
||||
"datarate": 50000
|
||||
},
|
||||
"tx_lut_0": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_1": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_2": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_3": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_4": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_5": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_6": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 9,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_7": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 6,
|
||||
"rf_power": 11,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_8": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 5,
|
||||
"rf_power": 13,
|
||||
"dig_gain": 2
|
||||
},
|
||||
"tx_lut_9": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 8,
|
||||
"rf_power": 14,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_10": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 6,
|
||||
"rf_power": 15,
|
||||
"dig_gain": 2
|
||||
},
|
||||
"tx_lut_11": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 6,
|
||||
"rf_power": 16,
|
||||
"dig_gain": 1
|
||||
},
|
||||
"tx_lut_12": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 9,
|
||||
"rf_power": 17,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_13": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 10,
|
||||
"rf_power": 18,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_14": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 11,
|
||||
"rf_power": 19,
|
||||
"dig_gain": 3
|
||||
},
|
||||
"tx_lut_15": {
|
||||
"pa_gain": 0,
|
||||
"mix_gain": 12,
|
||||
"rf_power": 20,
|
||||
"dig_gain": 3
|
||||
}
|
||||
},
|
||||
|
||||
"gateway_conf": {
|
||||
"gateway_ID": "XXXXXXXXXXXXXXXX",
|
||||
"server_address": "router.eu.thethings.network",
|
||||
"serv_port_up": 1700,
|
||||
"serv_port_down": 1700,
|
||||
"keepalive_interval": 10,
|
||||
"stat_interval": 30,
|
||||
"push_timeout_ms": 100,
|
||||
"forward_crc_valid": true,
|
||||
"forward_crc_error": false,
|
||||
"forward_crc_disabled": false
|
||||
}
|
||||
}
|
||||
```
|
||||
253
content/tutorials/all/ble_mesh.md
Normal file
253
content/tutorials/all/ble_mesh.md
Normal file
@@ -0,0 +1,253 @@
|
||||
---
|
||||
title: "Pymesh BLE Examples"
|
||||
aliases:
|
||||
- tutorials/all/ble_mesh.html
|
||||
- tutorials/all/ble_mesh.md
|
||||
- chapter/tutorials/all/ble_mesh
|
||||
---
|
||||
|
||||
Pymesh BLE module enables many-to-many device connections, based on the Bluetooth module.
|
||||
|
||||
For the API, please check the section [Pymesh BLE API](/firmwareapi/pycom/network/bluetooth/ble_mesh/).
|
||||
|
||||
## Generic OnOff Example
|
||||
Generic OnOff model is one of the simplest model in BLE Mesh.
|
||||
|
||||
This model illustrates the light-switches (OnOff Client) and light-bulbs (OnOff Server). In other words, the Client can send on/off commands to one/all nodes, and the Server is records state changes based on these commands.
|
||||
|
||||
### OnOff Server
|
||||
|
||||
OnOff Server has one boolean State. Server can Get, Set or send Status about this State to Client(s).
|
||||
|
||||
In the example below, during Provisioning, `Output OOB` can be selected. LED is yellow in case of Not-provisioned, and green in case of Provisioned state.
|
||||
|
||||
Changing the State of Server, LED's light is green or red.
|
||||
|
||||
```python
|
||||
from network import Bluetooth
|
||||
import pycom
|
||||
import time
|
||||
|
||||
BLE_Name = "OnOff Server 18"
|
||||
|
||||
def blink_led(n):
|
||||
for x in range(n):
|
||||
pycom.rgbled(0xffff00) # yellow on
|
||||
time.sleep(0.3)
|
||||
pycom.rgbled(0x000000) # off
|
||||
time.sleep(0.3)
|
||||
|
||||
def server_cb(new_state, event, recv_op):
|
||||
print("SERVER | State: ", new_state)
|
||||
|
||||
# Turn on LED on board based on State
|
||||
if new_state == True:
|
||||
pycom.rgbled(0x007f00) # green
|
||||
else:
|
||||
pycom.rgbled(0x7f0000) # red
|
||||
|
||||
def prov_callback(event, oob_pass):
|
||||
if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
|
||||
# Yellow if not Provision yet or Reseted
|
||||
pycom.rgbled(0x555500)
|
||||
if(event == BLE_Mesh.PROV_COMPLETE_EVT):
|
||||
# Green if Provisioned
|
||||
pycom.rgbled(0x007f00)
|
||||
if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT):
|
||||
print("Privisioning blink LED num:", oob_pass)
|
||||
blink_led(oob_pass)
|
||||
|
||||
# BLE Mesh module
|
||||
BLE_Mesh = Bluetooth.BLE_Mesh
|
||||
|
||||
# Turn off the heartbeat behavior of the LED
|
||||
pycom.heartbeat(False)
|
||||
|
||||
# Need to turn ON Bluetooth before using BLE Mesh
|
||||
bluetooth = Bluetooth()
|
||||
|
||||
# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
|
||||
element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
|
||||
model_server = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.SERVER, callback=server_cb)
|
||||
|
||||
# Initialize BLE_Mesh
|
||||
BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback)
|
||||
|
||||
# Turn on Provisioning Advertisement
|
||||
BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
|
||||
|
||||
print("\nBLE Mesh started")
|
||||
print(BLE_Name, "waits to be provisioned\n")
|
||||
|
||||
"""
|
||||
# After this node was provisioned
|
||||
# Current state can be read using
|
||||
model_server.get_state()
|
||||
"""
|
||||
```
|
||||
|
||||
### OnOff Client
|
||||
|
||||
Client can Get or Set State of Server. In case of Get, or Server Status, Client Gets the Status through the Model's callback.
|
||||
|
||||
```python
|
||||
from network import Bluetooth
|
||||
import pycom
|
||||
import time
|
||||
|
||||
BLE_Name = "OnOff Client 17"
|
||||
|
||||
def blink_led(n):
|
||||
for x in range(n):
|
||||
pycom.rgbled(0xffff00) # yellow on
|
||||
time.sleep(0.3)
|
||||
pycom.rgbled(0x000000) # off
|
||||
time.sleep(0.3)
|
||||
|
||||
def client_cb(new_state, event, recv_op):
|
||||
print("CLIENT | State: ", new_state)
|
||||
|
||||
def prov_callback(event, oob_pass):
|
||||
if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
|
||||
# Yellow if not Provision yet or Reseted
|
||||
pycom.rgbled(0x555500)
|
||||
if(event == BLE_Mesh.PROV_COMPLETE_EVT):
|
||||
# Green if Provisioned
|
||||
pycom.rgbled(0x007f00)
|
||||
if(event == BLE_Mesh.PROV_OUTPUT_OOB_REQ_EVT):
|
||||
print("Privisioning blink LED num:", oob_pass)
|
||||
blink_led(oob_pass)
|
||||
|
||||
# BLE Mesh module
|
||||
BLE_Mesh = Bluetooth.BLE_Mesh
|
||||
|
||||
# Turn off the heartbeat behavior of the LED
|
||||
pycom.heartbeat(False)
|
||||
|
||||
# Need to turn ON Bluetooth before using BLE Mesh
|
||||
bluetooth = Bluetooth()
|
||||
|
||||
# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
|
||||
element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
|
||||
model_client = element.add_model(BLE_Mesh.GEN_ONOFF, BLE_Mesh.CLIENT, callback=client_cb)
|
||||
|
||||
# Initialize BLE_Mesh
|
||||
BLE_Mesh.init(BLE_Name, auth=BLE_Mesh.OOB_OUTPUT, callback=prov_callback)
|
||||
|
||||
# Turn on Provisioning Advertisement
|
||||
BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
|
||||
|
||||
print("\nBLE Mesh started")
|
||||
print(BLE_Name, "waits to be provisioned\n")
|
||||
|
||||
"""
|
||||
# After this node was provisioned
|
||||
# transmit the change of state broadcasting in the Mesh
|
||||
|
||||
model_client.set_state(False, 0xFFFF)
|
||||
model_client.set_state(True, 0xFFFF)
|
||||
|
||||
# or to a unique server
|
||||
model_client.set_state(False, 3)
|
||||
model_client.set_state(True, 5)
|
||||
|
||||
"""
|
||||
```
|
||||
|
||||
## Sensor Example
|
||||
In case of Sensor Models, State of Server can be modified only by Server itself, Client can only Get the State by calling Client's Get, or by Servers Status call, but cannot modify the Server's State.
|
||||
|
||||
### Sensor Server
|
||||
In this example Server takes a time measurement every 1 seconds, and send a Status message every 5 seconds, after it was provisioned.
|
||||
|
||||
```python
|
||||
from network import Bluetooth
|
||||
import pycom
|
||||
import time
|
||||
from machine import Timer
|
||||
|
||||
def read_sensor(alarm):
|
||||
# In this example sensor reads local seconds
|
||||
if(device_provisioned):
|
||||
model_server.set_state(time.localtime()[5])
|
||||
print("SENSOR | State: ", model_server.get_state())
|
||||
|
||||
def status_sensor(alarm):
|
||||
if (device_provisioned):
|
||||
model_server.status_state()
|
||||
|
||||
def prov_callback(event, oob_pass):
|
||||
global device_provisioned
|
||||
if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
|
||||
# Yellow if not Provision yet or Reseted
|
||||
pycom.rgbled(0x555500)
|
||||
device_provisioned = False
|
||||
if(event == BLE_Mesh.PROV_COMPLETE_EVT):
|
||||
# Green if Provisioned
|
||||
pycom.rgbled(0x007f00)
|
||||
device_provisioned = True
|
||||
|
||||
# BLE Mesh module
|
||||
BLE_Mesh = Bluetooth.BLE_Mesh
|
||||
|
||||
# Turn off the heartbeat behavior of the LED
|
||||
pycom.heartbeat(False)
|
||||
|
||||
# Need to turn ON Bluetooth before using BLE Mesh
|
||||
bluetooth = Bluetooth()
|
||||
|
||||
# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
|
||||
element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
|
||||
model_server = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.SERVER, sen_min = 0, sen_max = 59, sen_res = 1)
|
||||
|
||||
# Initialize BLE_Mesh
|
||||
BLE_Mesh.init("Pycom Sensor Server", callback=prov_callback)
|
||||
|
||||
# Turn on Provisioning Advertisement
|
||||
BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
|
||||
|
||||
# Sensor takes measurement every 1 second
|
||||
Timer.Alarm(read_sensor, 1, periodic=True)
|
||||
|
||||
# Sensor send status every 5 seconds
|
||||
Timer.Alarm(status_sensor, 5, periodic=True)
|
||||
```
|
||||
|
||||
### Sensor Client
|
||||
|
||||
Sensor Client is looking for measurements, as Server sends Status every 5 seconds. Between these calls, Client can Get message any time.
|
||||
|
||||
```python
|
||||
from network import Bluetooth
|
||||
import pycom
|
||||
|
||||
def client_cb(new_state, event, recv_op):
|
||||
print("CLIENT | State: ", new_state)
|
||||
|
||||
def prov_callback(event, oob_pass):
|
||||
if(event == BLE_Mesh.PROV_REGISTER_EVT or event == BLE_Mesh.PROV_RESET_EVT):
|
||||
# Yellow if not Provision yet or Reseted
|
||||
pycom.rgbled(0x555500)
|
||||
if(event == BLE_Mesh.PROV_COMPLETE_EVT):
|
||||
# Green if Provisioned
|
||||
pycom.rgbled(0x007f00)
|
||||
|
||||
# BLE Mesh module
|
||||
BLE_Mesh = Bluetooth.BLE_Mesh
|
||||
|
||||
# Turn off the heartbeat behavior of the LED
|
||||
pycom.heartbeat(False)
|
||||
|
||||
# Need to turn ON Bluetooth before using BLE Mesh
|
||||
bluetooth = Bluetooth()
|
||||
|
||||
# Create a Primary Element with GATT Proxy feature and add a Server model to the Element
|
||||
element = BLE_Mesh.create_element(primary=True, feature=BLE_Mesh.GATT_PROXY)
|
||||
model_client = element.add_model(BLE_Mesh.SENSOR, BLE_Mesh.CLIENT, callback=client_cb, sen_min = 0, sen_max = 59, sen_res = 1)
|
||||
|
||||
# Initialize BLE_Mesh
|
||||
BLE_Mesh.init("Pycom Sensor Client", callback=prov_callback)
|
||||
|
||||
# Turn on Provisioning Advertisement
|
||||
BLE_Mesh.set_node_prov(BLE_Mesh.PROV_ADV|BLE_Mesh.PROV_GATT)
|
||||
```
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
title: "LTE Examples"
|
||||
aliases:
|
||||
- chapter/tutorials/lte
|
||||
---
|
||||
|
||||
The following tutorials demonstrate the use of the LTE CAT-M1 and NB-IoT functionality on cellular enabled Pycom modules.
|
||||
|
||||
Our cellular modules support both LTE CAT-M1 and NB-IoT, these are new lower power, long range, cellular protocols. These are not the same as the full version of 2G/3G/LTE supported by cell phones, and require your local carriers to support them. At the time of writing, CAT-M1 and NB-IoT connectivity is not widely available so be sure to check with local carriers if support is available where you are.
|
||||
|
||||
|
||||
100
content/tutorials/lte/power.md
Normal file
100
content/tutorials/lte/power.md
Normal file
@@ -0,0 +1,100 @@
|
||||
---
|
||||
title: "LTE power consumption"
|
||||
aliases:
|
||||
- tutorials/lte/power.html
|
||||
- tutorials/lte/power.md
|
||||
- chapter/tutorials/power
|
||||
---
|
||||
|
||||
There are some trade offs one can do to reduce power consumption of the LTE modem. You can limit connectivity in exchange for saving power consumption.
|
||||
|
||||
Let's start with the simplest choice: Turn off or not. It's not very sophisticated, but for completeness, let's start with this:
|
||||
|
||||
|
||||
## Turn LTE modem off <a id="lte-power-off" ></a>
|
||||
|
||||
```python
|
||||
|
||||
from network import LTE
|
||||
import time
|
||||
import socket
|
||||
import machine
|
||||
import pycom
|
||||
|
||||
def attach():
|
||||
start = time.time()
|
||||
if lte.isattached():
|
||||
print("already attached")
|
||||
else:
|
||||
print("attach")
|
||||
lte.attach(band=20, apn="the.apn.to.be.used.with.your.simcard")
|
||||
while not lte.isattached():
|
||||
time.sleep(1)
|
||||
print("attached after", time.time() - start, "seconds")
|
||||
print(lte.psm())
|
||||
|
||||
def connect():
|
||||
print("connect")
|
||||
start = time.time()
|
||||
lte.connect()
|
||||
while not lte.isconnected():
|
||||
time.sleep(0.5)
|
||||
print("connected after", time.time() - start, "seconds")
|
||||
|
||||
def http_get(url = 'http://detectportal.firefox.com/'):
|
||||
_, _, host, path = url.split('/', 3)
|
||||
addr = socket.getaddrinfo(host, 80)[0][-1]
|
||||
s = socket.socket()
|
||||
s.connect(addr)
|
||||
s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
|
||||
s.close()
|
||||
|
||||
# main
|
||||
lte = LTE()
|
||||
attach()
|
||||
connect()
|
||||
http_get()
|
||||
print("deinit")
|
||||
lte.deinit()
|
||||
print("deepsleep")
|
||||
machine.deepsleep(55 * 60 * 1000) # 55m
|
||||
```
|
||||
|
||||
The example above is the simple case where we attach, connect, communicate and then turn the LTE modem off: `lte.deinit()`. This will make sure the LTE modem uses minimal power after the deinit. However, it means that the subsequent attach procedure after waking up will take some seconds. During this attach time the modem already consumes power.
|
||||
|
||||
## Leave LTE modem on
|
||||
|
||||
Depending on your use case, you may want to save the time (and energy) for reattching that you get after [turning the modem off](#lte-power-off).
|
||||
If your device communicates a lot, then you can choose to not turn it off at all, save the time for the reattach. However, you then trade the higher power consumption during any idle time. For this, simply remove the deinit from the example:
|
||||
|
||||
|
||||
```python
|
||||
# lte.deinit()
|
||||
```
|
||||
|
||||
## Power Saving Mode
|
||||
|
||||
A more sophisticated configuration, is the _Power Saving Mode_. PSM allows you to configure the period how often the device will connect and how long it will stay actively connected. During the sleep
|
||||
- the LTE modem will go into a low power state, but
|
||||
- it will stay attached to the network, thus no time is spent for `attach()` after waking up.
|
||||
|
||||
Note that the network needs to cooperate in this, so first there is a negotiation where you propose timers. Then you attach and the network will decide which timers to actually apply. Afterwards you can query the effective values.
|
||||
|
||||
So you see, here you not only need to make the trade off what is best for your application, but you will also need to do some testing to see which values your provider offers you and how this works out in your application in practise.
|
||||
|
||||
For the following example, assume you want to wake up once per hour, connect and do some processing, then go to deepsleep for 55 minutes. We would adjust the main part of the example as follows:
|
||||
|
||||
```python
|
||||
# main
|
||||
# period 1h, active 10s
|
||||
lte = LTE(psm_period_value=1, psm_period_unit=LTE.PSM_PERIOD_1H,
|
||||
psm_active_value=5, psm_active_unit=LTE.PSM_ACTIVE_2S )
|
||||
print(lte.psm())
|
||||
attach()
|
||||
connect()
|
||||
http_get()
|
||||
print("deinit")
|
||||
lte.deinit(detach=False, reset=False)
|
||||
print("deepsleep")
|
||||
machine.deepsleep(55 * 60 * 1000) # 55m
|
||||
```
|
||||
Reference in New Issue
Block a user