Pycom Documentation
  • Introduction
  • Pycom Products
  • Getting Started
    • Introduction
    • Hardware Setup
      • LoPy
      • LoPy 4
      • SiPy
      • GPy
      • FiPy
      • WiPy
    • Software
      • Drivers
      • Updating Firmware
      • Pymakr
    • Programming the modules
      • Introduction to MicroPython
      • MicroPython Examples
      • Your first Pymakr project
      • REPL
        • Serial USB (UART)
        • Telnet REPL
      • FTP
      • Safe boot
    • Device Registration
      • Sigfox
      • Cellular
      • LoRaWAN
        • The Things Network
        • Objenious
  • Pymakr Plugin
    • Installation
      • Atom
      • Visual Studio Code
    • Tools/Features
    • Settings
  • Pytrack, Pysense, Pyscan
    • Introduction
    • Installing Software
      • Updating Firmware
      • Installing Drivers - Windows 7
      • Installing Libraries
    • API Reference
      • Pytrack
      • Pysense
      • Pyscan
      • Sleep
  • Tutorials & Examples
    • Introduction
    • All Pycom Device Examples
      • REPL
      • WLAN
      • Bluetooth
      • HTTPS
      • MQTT
      • AWS
      • ADC
      • I2C
      • Onewire Driver
      • Threading
      • RGB LED
      • Timers
      • PIR Sensor
      • Modbus
      • OTA update
      • RMT
      • Socket
      • Touch
    • LoRa Examples
      • LoRa-MAC (Raw LoRa)
      • LoRaWAN with OTAA
      • LoRaWAN with ABP
      • LoRa-MAC Nano-Gateway
      • LoPy to LoPy
      • LoRaWAN Nano-Gateway
      • RN2483 to LoPy
      • LoRa Mesh
      • PyMesh Border Router
    • Sigfox Examples
    • LTE Examples
      • CAT-M1
      • NB-IoT
      • Module IMEI
      • Modem Firmware Update
    • Pytrack Examples
    • Pysense Examples
    • Pyscan Examples
  • Firmware & API Reference
    • Introduction
    • Pycom Modules
      • machine
        • ADC
        • DAC
        • I2C
        • Pin
        • PWM
        • RTC
        • SPI
        • UART
        • WDT
        • Timer
        • SD
        • CAN
        • RMT
      • network
        • WLAN
        • Server
        • Bluetooth
          • GATT
          • GATTCConnection
          • GATTCService
          • GATTCCharacteristic
          • GATTSService
          • GATTSCharacteristic
        • LoRa
          • Pymesh
        • Sigfox
        • LTE
      • AES
      • pycom
    • MicroPython Modules
      • micropython
      • uctypes
      • sys
      • uos
      • array
      • cmath
      • math
      • gc
      • ubinascii
      • ujson
      • ure
      • usocket
      • select
      • utime
      • uhashlib
      • ussl
      • ucrypto
      • ustruct
        • uzlib
      • _thread
      • Builtin
    • Notes
  • Product Info, Datasheets
    • Introduction
    • Development Modules
      • WiPy 2.0
      • WiPy 3.0
      • LoPy
      • LoPy 4
      • SiPy
      • GPy
      • FiPy
    • OEM Modules
      • W01
      • L01
      • L04
      • G01
      • L01 OEM Baseboard Reference
      • Universal OEM Baseboard Reference
    • Expansion Boards and Shields
      • Expansion Board 3.0
      • Pytrack
      • Pysense
      • Pyscan
      • Expansion Board 2.0
      • Deep Sleep Shield
        • Deep Sleep API
    • Notes
  • Pybytes
    • Introduction
    • Getting Started with Pybytes
    • Add a device to Pybytes
      • Connect to Pybytes: Quick Add
      • Connect to Pybytes: Flash Pybytes library manually
      • Add Sigfox device
        • DevKit contract
        • Custom contract
    • Visualise data from your device
    • Integrations
      • Amazon IoT
  • Documentation Notes
    • Introduction
    • Syntax
    • REPL vs Scripts
    • Mesh Networks
  • Advanced Topics
    • Firmware Downgrade
    • CLI Updater
    • SecureBoot and Encryption
    • License
  • Have a question?
    • Ask on the Forum
Powered by GitBook
On this page
  • Gateway Code
  • Node
  1. Tutorials & Examples
  2. LoRa Examples

LoRa-MAC Nano-Gateway

PreviousLoRaWAN with ABPNextLoPy to LoPy

Last updated 6 years ago

This example allows a raw LoRa connection between two LoPys (nodes) to a single LoPy acting as a Nano-Gateway.

For more information and discussions about this code, see this forum .

Gateway Code

import socket
import struct
from network import LoRa

# A basic package header, B: 1 byte for the deviceId, B: 1 byte for the pkg size, %ds: Formatted string for string
_LORA_PKG_FORMAT = "!BB%ds"
# A basic ack package, B: 1 byte for the deviceId, B: 1 byte for the pkg size, B: 1 byte for the Ok (200) or error messages
_LORA_PKG_ACK_FORMAT = "BBB"

# Open a LoRa Socket, use rx_iq to avoid listening to our own messages
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORA, rx_iq=True, region=LoRa.EU868)
lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
lora_sock.setblocking(False)

while (True):
    recv_pkg = lora_sock.recv(512)
    if (len(recv_pkg) > 2):
        recv_pkg_len = recv_pkg[1]

        device_id, pkg_len, msg = struct.unpack(_LORA_PKG_FORMAT % recv_pkg_len, recv_pkg)

# If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
        print('Device: %d - Pkg:  %s' % (device_id, msg))

        ack_pkg = struct.pack(_LORA_PKG_ACK_FORMAT, device_id, 1, 200)
        lora_sock.send(ack_pkg)

The _LORA_PKG_FORMAT is used as a method of identifying the different devices within a network. The _LORA_PKG_ACK_FORMAT is a simple ack package as a response to the nodes package.

Node

import os
import socket
import time
import struct
from network import LoRa

# A basic package header, B: 1 byte for the deviceId, B: 1 byte for the pkg size
_LORA_PKG_FORMAT = "BB%ds"
_LORA_PKG_ACK_FORMAT = "BBB"
DEVICE_ID = 0x01


# Open a Lora Socket, use tx_iq to avoid listening to our own messages
# Please pick the region that matches where you are using the device:
# Asia = LoRa.AS923
# Australia = LoRa.AU915
# Europe = LoRa.EU868
# United States = LoRa.US915
lora = LoRa(mode=LoRa.LORA, tx_iq=True, region=LoRa.EU868)
lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
lora_sock.setblocking(False)

while(True):
    # Package send containing a simple string
    msg = "Device 1 Here"
    pkg = struct.pack(_LORA_PKG_FORMAT % len(msg), DEVICE_ID, len(msg), msg)
    lora_sock.send(pkg)

    # Wait for the response from the gateway. NOTE: For this demo the device does an infinite loop for while waiting the response. Introduce a max_time_waiting for you application
    waiting_ack = True
    while(waiting_ack):
        recv_ack = lora_sock.recv(256)

        if (len(recv_ack) > 0):
            device_id, pkg_len, ack = struct.unpack(_LORA_PKG_ACK_FORMAT, recv_ack)
            if (device_id == DEVICE_ID):
                if (ack == 200):
                    waiting_ack = False
                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                    print("ACK")
                else:
                    waiting_ack = False
                    # If the uart = machine.UART(0, 115200) and os.dupterm(uart) are set in the boot.py this print should appear in the serial port
                    print("Message Failed")

    time.sleep(5)

The node is always sending packages and waiting for the ack from the gateway.

To adapt this code to user specific needs:

  • Put a max waiting time for the ack to arrive and resend the package or mark it as invalid

  • Reduce the package size with bitwise manipulation

  • Reduce the message size (for this demo, a string) to something more useful for specific development

Increase the package size changing the _LORA_PKG_FORMAT to BH%ds. The H will allow the keeping of 2 bytes for size (for more information about )

post
struct format