Publication LoRaWAN de mesures environnementales avec un module LoRa-E5
Ce tutoriel explique comment mettre en œuvre une publication LoRaWAN sur The Things Network (TTN) avec une intégration TagoIO en utilisant un pilote MicroPython pour un module Grove LoRa-E5 côté objet.
Pour en apprendre un peu plus sur LoRa et LoRaWAN, vous pouvez consulter cette page et pour vraiment tout comprendre lisez ce document de Sylvain Montagny (Université de Savoie - Mont Blanc). Vous trouverez d’autres références à la fin de ce tutoriel.
Matériel requis et montage
Notre système connecté sera constitué des composants suivants :
- Pour la communication LoRa / LoRaWAN côté objet, nous avons choisi un module Grove LoRa-E5 de Seeed studio, basé sur un système sur puce (SoC) STM32WLE5JC de STMicroelectronics.
- Une carte d’extension de base Grove avec son commutateur d’alimentation en position 3.3V
- Une carte NUCLEO-WB55
- Un module Grove BME280
- Pour la passerelle LoRaWAN, nous avons choisi la The Things Indoor Gateway (TTIG).
Un module Grove LoRa-E5 | Une passerelle LoRa-WiFi TTIG |
---|---|
Crédit image : Seeed Studio | Crédit image : The Things Network |
Placez la carte d’extension Grove sur la carte NUCLEO et connectez-y le module BME280 (sur l’un des connecteurs Grove “I2C”) et le module LoRa-E5 (sur le connecteur Grove “UART”).
Première étape : Obtention du DevEUI du module LoRa-E5
Le module Grove LoRa-E5 est piloté à l’aide de “commandes AT”. Ceci signifie que Seeed Studio l’a programmé avec un firmware qui reçoit des commandes en mode texte et y répond, également par du texte, au moyen du protocole série. La même stratégie est souvent utilisée pour piloter des modules GPS, Wi-Fi ou Bluetooth. La documentation des commandes AT du module est disponible ici.
Dans cette première partie, nous allons utiliser une commande AT pour interroger le module et obtenir son DevEUI, un identifiant unique encodé sur 64 bits qui servira pour son enregistrement sur le réseau LoRaWAN de TTN.
Le script MicroPython
Le script présenté ci-après est disponible dans cette archive ZIP.
Pour envoyer des commandes AT au module et obtenir ses réponses, il est donc nécessaire d’utiliser un script MicroPython pour échanger sur l’UART auquel est connecté le module. C’est précisément la fonction du script qui suit, inspiré des exemples donnés sur cette page.
Créez un script main.py sur votre ordinateur et copiez-y le code suivant, puis glissez-déplacez le dans PYBFLASH :
# Objet du script : Emission / Réception de messages via UART en mode ligne de commande
# Ce script est utile pour dialoguer avec des modules dotés de firmwares AT.
from machine import UART # Pour piloter l'UART
# Constantes relatives au paramétrage de l'UART
DELAY_TIMEOUT = const(1000) # Durée (en millisecondes) pendant laquelle l'UART attend de reçevoir un message
BAUDRATE = const(9600) # Débit, en bauds, de la communication série
UART_NUMBER = const(2) # Identifiant de l'UART de la carte NUCLEO-WB55 qui sera utilisé
RX_BUFF = const(512) # Taille du buffer de réception (les messages reçus seront tronqués
# à ce nombre de caractères)
EOC = "\r\n" # Terminaison de commande pour valider l'envoi
# Initialisation de l'UART
uart = UART(UART_NUMBER, BAUDRATE, timeout = DELAY_TIMEOUT, rxbuf = RX_BUFF)
# Fonction de service de l'interruption de réception de l'UART
@micropython.native # Optimise le bytecode pour STM32
def Reception(uart_object):
# Lecture des caractères reçus
message_received = uart_object.read()
# Si réception d'un message
if not (message_received is None):
# Affiche le message reçu
print("Message reçu : \r\n" + message_received.decode("utf-8"))
# On active l'interruption de l'UART (vecteur d'interruption) pour la réception
irq_uart = uart.irq(Reception, UART.IRQ_RXIDLE, False)
# Pour gérer l'envoi de messages
@micropython.native # Optimise le bytecode pour STM32
def Emission():
print("Entrez votre commande")
while True:
# Prompt de saisie d'un message (au clavier)
message_sent = input()
# Envoi du message saisi
uart.write(message_sent + EOC)
print("Envoyé : " + str(message_sent))
# Appel de la fonction principale
Emission()
On remarquera que le baudrate du module LoRa-E5 est par défaut fixé à 9600. Cela peut être modifié par une autre commande AT, mais nous ne vous conseillons pas de le faire sans une bonne raison.
Mise en œuvre
Connectez un terminal PuTTY au firmware de la carte, comme indiqué ici (systèmes Windows), et lancez le script avec [CTRL]-[D]. Pour vous assurer que tout fonctionne bien tapez simplement AT dans le terminal, puis ENTER. La console PuTTY devrait ressembler à ceci :
MicroPython v1.20.0 on 2023-04-26; NUCLEO-WB55 with STM32WB55RGV6
Type "help()" for more information.
>>>
MPY: sync filesystems
MPY: soft reboot
Entrez votre commande
AT
Envoyé : AT
Message reçu : +AT: OK
Tout va bien, le module vous a répondu +AT: OK comme prévu.
A présent, tapez AT+ID et ENTER, vous devriez obtenir une réponse de cette forme :
AT+ID
Envoyé : AT+ID
Message reçu :
+ID: DevAddr, 44:10:BA:4A
+ID: DevEui, 2C:F7:F1:20:44:10:BA:4A
+ID: AppEui, 00:00:00:00:00:00:00:00
Notre module renvoie trois clefs dont DevEUI, qui servira à le connecter à un futur réseau LoRaWAN. Elle sera bien sûr différente pour votre module puisqu’il s’agit d’un identifiant unique. Notez la valeur de DevEui, vous en aurez besoin dans la deuxième étape ci-après. L’autre clef importante est AppEui, qui ne restera pas “à zéro” et sera fournie par TTN à l’issue de la deuxième étape. Pour en savoir plus sur la signification de ces clefs, vous pouvez consulter cette page.
Deuxième étape :
- Création d’un réseau LoRaWAN privé avec la passerelle TTIG pour un module LoRa-E5
- Création d’un lien entre TTN et l’intégration TagoIO
Pour la configuration de la passerelle et de tous les services permettant de recueillir les mesures du module loRa-E5 d’abord sur TTN puis sur TagoIO, nous vous renvoyons à ce tutoriel. Pour aller jusqu’au bout, vous aurez besoin de la clef DevEui obtenue ci-avant, à la première étape.
Troisième étape : Connexion du module LoRa-E5 au réseau LoRaWAN
Votre réseau LoRaWAN privé étant fonctionnel, vous pouvez à présent valider que le module LoRa-E5 parvient à s’y connecter.
Le script MicroPython
Le script présenté ci-après est disponible dans cette archive ZIP.
Commencez par copier les bibliothèques pour gérer la communication LoRa dans le dossier PYBFLASH ; il s’agit des fichiers stm32_driverAT.py et stm32_LoRa.py. Ces bibliothèques proviennent des ressources partagées en ligne ici par notre partenaire la société Vittascience. Elles ont été développées pour le kit Station de mesures connectée - version NUCLEO-L476.
Créez ensuite un script main.py sur votre ordinateur et copiez-y le code suivant, puis glissez-déplacez le dans PYBFLASH :
# Objet du script :
# Valider la connexion d'un module LoRa-E5 à un réseau LoRaWAN privé sur TTN,
# préalablement configuré.
# Cet exemple est obtenu à partir des ressources mises à disposition par
# Vittascience :
# https://github.com/vittascience/stm32-libraries/tree/main/grove_modules
# Importation des différents pilotes
import machine
from stm32_LoRa import *
from utime import sleep_ms
# Port série de la NUCLEO_WB55
UART_WB55 = const(2)
# Identifiants sur le réseau LoRaWAN
devAddr = '44 10 BA 4A'
appEui = '00 00 00 00 00 00 00 00'
appKey = '55 10 67 98 B2 15 EE 4E D0 33 19 DC 65 27 88 AB'
# Temporisations diverses
DelayRebootLostConnection = 300 # Exprimé en minutes
DelayTryJoin = 10 # Exprimé en secondes
MaxTryJoin = int((DelayRebootLostConnection * 60) / DelayTryJoin)
DelaySend = 30 # Exprimé en secondes
# Initialisation du module LoRa-E5
loRa = LoRa(9600, UART_WB55, DataReceiveCallback = None)
# Paramètres d'identification du module pour sa connexion au réseau LoRaWAN
status = loRa.setIdentify(DevAddr = devAddr,AppEui = appEui,AppKey = appKey)
# Affichage des différents paramètres du réseau LoRaWAN
def PrintLoRaParameters():
identify = loRa.getIdentify()
if(identify != -1):
print("#####################################################################")
print("########## INITIALIZE ########")
print("#####################################################################")
print("LORA_DRIVER_VERSION: " + loRa.getDriverVersion())
print("#### " + loRa.getMode() + " ####")
print("#### AppKey: " + identify['AppKey'])
print("#### DevEUI: " + identify['DevEui'])
print("#### AppEUI: " + identify['AppEui'])
print("#### DevAddr: " + identify['DevAddr'])
else:
print("#### = Read identify fail.\nReboot!")
sleep_ms(2000)
machine.reset()
if status == -1:
print("#### = Initialize fail.\nReboot!")
sleep_ms(2000)
machine.reset()
else:
print("#### = Initialize success.")
# Etablissement de la connexion ("join") LoRaWAN
def JoinNetwork():
# Essaie de se connecter au réseau
joinStatus = False
tryJoin = 0
while joinStatus == False:
# Join LoRaWAN
print("#### = Try join n°" + str(tryJoin + 1))
status = loRa.join()
if status == -1:
print("#### = Join Fail, retry in " + str(DelayTryJoin) + " seconds.")
tryJoin += 1
# Si MaxTryJoin tentatives de connexion ont échoué
if tryJoin > MaxTryJoin:
# Reboot de la carte
print("Reboot!")
machine.reset()
sleep_ms(DelayTryJoin * 1000)
else:
joinStatus = True
print("#### = Join sucess.")
# Exécution des fonctions
PrintLoRaParameters() # Affichage des paramètres
JoinNetwork() # Join
Mise en œuvre
Appuyez sur [CTRL]-[D] dans le terminal PuTTY. Si tout est correct, vous devriez observer dans le terminal la confirmation du “join” LoRAWAN (message “Join sucess”) :
MicroPython v1.20.0 on 2023-04-26; NUCLEO-WB55 with STM32WB55RGV6
Type "help()" for more information.
>>>
MPY: sync filesystems
MPY: soft reboot
#####################################################################
########## INITIALIZE ########
#####################################################################
LORA_DRIVER_VERSION: 1.0.1
#### LWOTAA ####
#### AppKey: "55 10 67 98 B2 15 EE 4E D0 33 19 DC 65 27 88 AB"
#### DevEUI: 2C F7 F1 20 42 00 1A 4A
#### AppEUI: 00 00 00 00 00 00 00 00
#### DevAddr: 44 10 BA 4A
#### = Initialize success.
#### = Try join n°1
#### = Join sucess.
MicroPython v1.20.0 on 2023-04-26; NUCLEO-WB55 with STM32WB55RGV6
Type "help()" for more information.
>>>
Enfin, si vous allez sur le site TTN avec un navigateur web, sur cette page (bien sûr après avoir suivi pas à pas le tutoriel de la Deuxième étape !) vous devriez y trouver aussi la confirmation du “join” :
C’est bon, votre objet est à présent connecté, vous pouvez désormais l’utiliser pour poster des mesures sur Internet !
Complément : Utilisation de l’IDE en ligne de Vittascience pour générer un script MicroPython
Pour gagner du temps sur la création du main.py qui précède, nous avons utilisé l’interface de programmation par blocs en ligne de la société Vittascience pour la NUCLEO-L476RG, qui propose la génération automatique de code LoRaWAN pour MicroPython :
- Nous avons commencé par placer l’interface en mode hybride avec ce bouton, de sorte à visualiser à la fois le code en blocs et en MycroPython dans la fenêtre de l’IDE :
- Ensuite nous avons glissé-déplacé le bloc [LoRa E5] initialiser le module avec l’appEUI “…” disponible dans la boite à outils Communication à l’intérieur du bloc Au démarrage :
- Enfin nous avons copié le code MicroPython depuis le volet de droite du navigateur dans un fichier texte, avant de le retoucher avec Notepad++, pour aboutir au script affiché ci-avant.
Nous avons procédé de même pour le script main.py de la quatrième partie qui suit, en ajoutant un bloc [LoRa E5] envoyer des données paramétré pour trois capteurs parmi ceux disponibles avec l’IDE Vittascience, puis en le modifiant pour l’adapter à notre exemple.
Quatrième étape : Publication des mesures du BME280 sur le réseau LoRaWAN
Maintenant que votre module LoRa-E5 est enregistré sur TTN et que nous avons pu vérifier qu’il s’y connecte, nous pouvons nous concentrer sur le script MicroPython qui va lui permettre de poster ses mesures de température, d’humidité et de pression dans un format hexadécimal compact approprié pour les trames LoRaWAN. Ceci signifie que nous devrons également configurer sur notre compte TagoIO un script en langage NodeJS pour extraire ces mesures des trames LoRaWAN et les “décoder” avant de les afficher dans un dashboard.
Le script MicroPython
Le script présenté ci-après est disponible dans cette archive ZIP.
Commencez par copier stm32_driverAT.py, stm32_LoRa.py et bme280.py dans PYBFLASH. Créez ensuite un script main.py sur votre ordinateur et copiez-y le code suivant, puis glissez-déplacez le dans PYBFLASH :
# Objet du script :
# Connexion d'un module LoRa-E5 à un réseau LoRaWAN privé sur TTN, préalablement configuré.
# Publication de données de température, humidité et pression sur TTN dans un format
# hexadécimal qui devra ensuite être "décodé" par un parser de payloads sur TagoIO.
# Cet exemple a été construit à partir des ressources mises à disposition par
# Vittascience :
# https://github.com/vittascience/stm32-libraries/tree/main/grove_modules
# Importation des différents pilotes
import machine
from stm32_LoRa import *
from utime import sleep_ms
# Port série de la NUCLEO_WB55
UART_WB55 = const(2)
# Identifiants pour le réseau LoRaWAN
devAddr = '44 10 BA 4A' # Obtenue avec la commande AT+ID adressée au module
appEui = '00 00 00 00 00 00 00 00' # Conservez cette valeur
appKey = '09 5E 59 17 36 EC 60 12 8D 2C E4 83 19 EA 13 86' # Obtenue par TTN
# Temporisations diverses
DelayRebootLostConnection = 300 # Exprimé en minutes
DelayTryJoin = 10 # Exprimé en secondes
MaxTryJoin = int((DelayRebootLostConnection * 60) / DelayTryJoin)
DelaySend = 30 # Exprimé en secondes
# Fonction de callback chargée de traiter et réagir aux messages envoyés par le serveur
# LoRaWAN au module LoRa-E5
def DataReceived(Port = 0, DataReceived = b''):
print("#### = Data received")
print("Data received on PORT: " + str(Port) +
", Size = "+ str(len(DataReceived)) +
", Data = "+str([hex(x) for x in list(DataReceived)]))
# Initialisation du module LoRa-E5
loRa = LoRa(9600, UART_WB55, DataReceiveCallback = DataReceived)
# Paramètres d'identification du module pour sa connexion au réseau LoRaWAN
status = loRa.setIdentify(DevAddr = devAddr,AppEui = appEui,AppKey = appKey)
# Affichage des différents paramètres du réseau LoRaWAN
def PrintLoRaParameters():
identify = loRa.getIdentify()
if(identify != -1):
print("#####################################################################")
print("########## INITIALIZE ########")
print("#####################################################################")
print("LORA_DRIVER_VERSION : " + loRa.getDriverVersion())
print("#### " + loRa.getMode() + " ####")
print("#### AppKey: " + identify['AppKey'])
print("#### DevEUI: " + identify['DevEui'])
print("#### AppEUI: " + identify['AppEui'])
print("#### DevAddr: " + identify['DevAddr'])
else:
print("#### = Read identify fail.\nReboot!")
sleep_ms(2000)
machine.reset()
if status == -1:
print("#### = Initialize fail.\nReboot!")
sleep_ms(2000)
machine.reset()
else:
print("#### = Initialize success.")
# Etablissement de la connexion ("join") LoRaWAN
def JoinNetwork():
# Try to join network
joinStatus = False
tryJoin = 0
while joinStatus == False:
# Join LoRaWAN
print("#### = Try join n°" + str(tryJoin + 1))
status = loRa.join()
if status == -1:
print("#### = Join Fail, retry in " + str(DelayTryJoin) + " seconds.")
tryJoin += 1
if tryJoin > MaxTryJoin:
# Reboot board
print("Reboot!")
machine.reset()
sleep_ms(DelayTryJoin * 1000)
else:
joinStatus = True
print("#### = Join sucess.")
# Emission de trames dans un format hexadécimal contenant les mesures du BME280
def GetSendData():
# Temporisation en millisecondes, fréquence d'émission des trames
TEMPO = const(600000)
from time import sleep_ms # Pout temporiser
from machine import I2C # Pilote du bus I2C
import bme280 # Pilote du capteur
# On utilise l'I2C n°1 de la carte NUCLEO-WB55 pour communiquer avec le capteur
i2c1 = I2C(1)
# Pause d'une seconde pour laisser à l'I2C le temps de s'initialiser
sleep_ms(1000)
# Liste des adresses I2C des périphériques présents
print("Adresses I2C utilisées : " + str(i2c1.scan()))
# Instanciation du capteur
sensor = bme280.BME280(i2c=i2c1)
# Décompte des tentatives d'émission d'une trame
trySend = 0
# Nombres d'octets dans la payload
NB_BYTES = const(5)
# Initialisation d'un tableau de NB_BYTES octets qui contiendra la payload LoRaWAN
LoRaPayload = [0x00] * NB_BYTES
while True:
# Lecture des valeurs mesurées
bme280data = sensor.values
# Préparation des mesures
temp = bme280data[0]
press = bme280data[1]
humi = bme280data[2]
# Affichage des mesures
print('=' * 40) # Imprime une ligne de séparation
print("Température : %.1f °C" %temp)
print("Pression : %d hPa" %press)
print("Humidité relative : %d %%" %humi)
# On convertit les mesures de température, pression et humidité en entiers
temp = int(temp * 10)
press = int(press * 10)
humi = int(humi * 2)
# Construction de la payload LoRaWAN, on agrège directement les données au format hexadécimal
# Température, donnée codée sur 16 bits
LoRaPayload[0] = (temp >> 8) & 0xFF # Extraction de l'octet de poids faible
LoRaPayload[1] = temp & 0xFF # Extraction de l'octet de poids fort
# Pression, donnée codée sur 16 bits
LoRaPayload[2] = (press >> 8) & 0xFF # Extraction de l'octet de poids faible
LoRaPayload[3] = press & 0xFF # Extraction de l'octet de poids fort
# Humidité, donnée codée sur un seul octet
LoRaPayload[4] = humi
# Emission de la trame LoRaWAN
print("#### = Send data.")
trySend += 1
sendStatus = loRa.sendData(LoRaPayload, Port=1, NeedAck= False)
# Si l'émission échoue, reessaye trySend fois puis force un reset du STM32WB55
if sendStatus == -1:
print("#### = Join fail.")
if trySend > MaxTrySend:
print("Reset!")
machine.reset()
else:
print("#### = Send success.")
trySend = 0
# Place le module LoRa-E5 en mode veille
print("#### = LoRa module enter low power mode.")
loRa.enterLowPowerMode()
# Temporisation jusqu'à l'envoi de la prochaine trame
# Place le STM32WB55 en mode "sommeil profond"
# Le réveil génère un reset.
print("#### = MCU enter low power mode for %d seconds" %(TEMPO/1000))
machine.deepsleep(TEMPO) # Impose un reset du script après TEMPO millisecondes
# machine.lightsleep(TEMPO) # Le script redémarre à ce point après TEMPO millisecondes
# Alternative au mode "sommeil" pour ne pas perdre
# la connexion au RPL en phase de développement
# sleep_ms(TEMPO)
# Exécution des fonctions
PrintLoRaParameters() # Affichage des paramètres
JoinNetwork() # Connexion à TTN
GetSendData() # Emission de trames vers TagoIO
Remarque : augmenter l’autonomie de l’objet avec “Deep Sleep” et “Light Sleep”
La raison d’être de LoRaWAN est de transmettre très peu d’informations à une très faible fréquence afin que l’objet connecté puisse fonctionner aussi longtemps que possible sur batterie. De ce fait, notre script prend soin de mettre en sommeil le module LoRa-E5 via l’instruction loRa.enterLowPowerMode()
mais aussi le MCU STM32WB55RG par l’instruction machine.deepsleep(TEMPO)
.
Au moment où celle-ci est exécutée, la connexion est automatiquement perdue avec l’invite de commandes REPL sous PuTTY puisque tous les périphériques internes du MCU sont éteints pour économiser l’énergie, notamment l’UART qui assure le lien entre la console REPL et PuTTY. Le contenu de la SRAM (donc, l’état du programme) est également perdu dans ce mode car celle-ci n’est plus alimentée. Le réveil après TEMPO
millisecondes génère un “RESET” du MCU, ce qui fait que le script redémarre, refait une requête de join, etc. Accessoirement, on remarquera que, dans cette configuration de redémarrages périodiques forcés, l’instruction while True:
ne sert plus à rien.
Si on souhaite plutôt mettre la boucle en pause puis que le script redémarre au point où il s’était arrêté, il faut utiliser machine.lightsleep(TEMPO)
à la place de machine.deepsleep(TEMPO)
. La connexion avec la console REPL sur le PC sera toujours interrompue périodiquement, mais le script ne passera pas par un “RESET”, car le contenu de la SRAM est préservé par “Light Sleep”. En contrepartie, le MCU consommera un peu plus pendant ses TEMPO
millisecondes de sommeil ce qui réduira l’autonomie de l’objet.
Pour plus d’informations sur les instructions de mise en sommeil du MCU, vous pouvez consulter la documentation de MicroPython.
Important : devEui, devAddr, appEui et appKey
Afin que l’objet puisse établir une connexion avec les serveurs de TTN, il faut être attentif aux valeurs de devAddr, appEUI et appKey et devEui.
- La valeur de devAddr est obtenue en interrogeant le module LoRa-E5 avec une commande AT (voir première partie de ce tutoriel). En fait sa valeur est arbitraire, ce qui compte c’est qu’elle soit renseignée à l’identique dans l’interface de gestion de l’objet par TTN (voir cet autre tutoriel).
- La valeur de appEui doit rester à ‘00 00 00 00 00 00 00 00’. Là encore, sa valeur est arbitraire, ce qui compte c’est qu’elle soit renseignée à l’identique dans l’interface de gestion de l’objet de TTN (voir cet autre tutoriel).
- La valeur de appKey est obtenue au moment de la création d’une application dans TTN (voir cet autre tutoriel).
- La valeur de devEui nous a servi pour obtenir appKey via TTN (voir la deuxième partie de ce tutoriel). En fait, il n’y a pas besoin de la renseigner car le script MicroPython la retrouve tout seul en interrogeant le module LoRa-E5 avec une commande AT comme nous l’avons fait dans la première partie de ce tutoriel.
Optionnel : Configuration des canaux de communication pour TTN
Le blog sur l’IoT disk91.com signale, dans sa revue du module LoRa-E5, qu’il est nécessaire d’adresser au module les commandes AT qui suivent pour configurer de façon optimale la communication avec TTN :
# channel configuration for Europe
AT+CH=3,867.1,DR0,DR5
AT+CH=4,867.3,DR0,DR5
AT+CH=5,867.5,DR0,DR5
AT+CH=6,867.7,DR0,DR5
AT+CH=7,867.9,DR0,DR5
Idéalement, ces commandes devraient être intégrées dans l’initialisation du pilote LoRaWN stm32_LoRa.py.
Mise en œuvre
Appuyez sur [CTRL]-[D] dans le terminal PuTTY. Si tout est correct, vous devriez lire dans le terminal la confirmation de publication régulière, toutes les dix minutes, de trames LoRaWAN à l’attention des serveurs de TTN :
>>>
MPY: sync filesystems
MPY: soft reboot
#####################################################################
########## INITIALIZE ########
#####################################################################
LORA_DRIVER_VERSION : 1.0.1
#### LWOTAA ####
#### AppKey: "55 10 67 98 B2 15 EE 4E D0 33 19 DC 65 27 88 AB"
#### DevEUI: 2C F7 F1 20 42 00 1A 4A
#### AppEUI: 00 00 00 00 00 00 00 00
#### DevAddr: 44 10 BA 4A
#### = Initialize success.
#### = Try join n°1
#### = Join sucess.
Adresses I2C utilisées : [118]
========================================
Température : 23.7 °C
Pression : 628 hPa
Humidité relative : 66 %
#### = Send data.
#### = Send success.
#### = LoRa module enter low power mode.
========================================
Température : 25.0 °C
Pression : 958 hPa
Humidité relative : 47 %
#### = Send data.
#### = Send success.
#### = LoRa module enter low power mode.
Complément : Downlink et receipt callback ?
Le script ci-avant contient une fonction chargée du traitement à la réception de données descendantes depuis le serveur TTN sur le module LoRa-E5 :
# Fonction de callback chargée de traiter et réagir aux messages envoyés par le serveur
# LoRaWAN au module LoRa-E5
def DataReceived(Port = 0, DataReceived = b''):
print("#### = Data received")
print("Data received on PORT: " + str(Port) +
", Size = "+ str(len(DataReceived)) +
", Data = "+str([hex(x) for x in list(DataReceived)]))
Le protocole LoRaWAN permet en effet une communication bidirectionnelle objet <-> serveur. Dans le cas de l’application TTN “gratuite”, cette fonction n’est pas très utile, mais nous pouvons néanmoins vérifier qu’elle fonctionne.
Pour envoyer un message depuis TTN au module LoRa-E5 …
- Rendez-vous sur la page de votre device ;
- Puis, dans le menu vertical à gauche, choisissez End devices ;
- Cliquez sur le device concerné ;
- Sélectionnez le sous menu Messaging ;
- Sélectionnez le sous-sous-menu Downlink;
- Finalement, entrez une valeur hexadécimale dans la boite Payload (deux caractères, simplement “0A” dans notre cas) et cliquez sur le bouton Schedule downlink en bas. Un message Downlink scheduled, en bas à droite, confirme que l’opération est planifiée. Pour notre device, voici l’aspect de la page de downlink sur le site de TTN à ce moment :
- Il vous faut attendre le prochain uplink du module LoRa-E5 vers le serveur TTN. Une fois celui-ci réalisé, le message du serveur est bien reçu par le module, comme le confirment les logs sur le terminal PuTTY :
========================================
Température : 26.4 °C
Pression : 957 hPa
Humidité relative : 52 %
#### = Send data.
#### = Data received
Data received on PORT: 1, Size = 1, Data = ['0xA']
#### = Send success.
#### = LoRa module enter low power mode.
Visualisation des mesures sur TTN puis sur TagoIO
Visualisation sur TTN
Les trames sont d’abord envoyées de la NUCLEO-WB55, par le module LoRa-E5, à la passerelle, qui les communique au serveur TTN. Nous pouvons donc vérifier que ce dernier les reçoit comme prévu. Connectez vous sur la page de votre application (nous vous renvoyons au tutoriel de la deuxième étape) :
En cliquant sur le lien “See all activity” (au milieu, à droite), vous aurez accès à toutes les transactions, horodatées.
Visualisation sur TagoIO : “parsing” des trames LoRaWAN et création d’un tableau de bord
Pour visualiser les données reçues sur TTN dans une intégration TagoIO …
La première étape consiste à créer un webhook, un lien, entre ces deux plateformes. La procédure correspondante est donnée à la fin de cet autre tutoriel que vous devriez déjà avoir suivi à ce stade.
La deuxième étape consiste à configurer un “parser de payloads” LoRaWAN dans votre compte TagIO, de sorte que celui-ci soit capable de transformer les données hexadécimales qu’il reçoit de TTN (i.e. le contenu de la payload d’uplink) en valeurs lisibles de température, pression et humidité (pour notre exemple en particulier). Pour cela, une fois dans votre compte TagoIO …
- Cliquez sur le bouton Devices, puis double clic sur la ligne du device.
- Cliquez dans l’onglet Payload Parser.
- Dans l’onglet Payload Parser, activez le commutateur Run your own parser.
- Collez votre script de parser de payloads LoRaWAN dans la boite de texte intitulée Load as snipet. Pour ne pas rallonger encore ce (très long) tutoriel, nous ne reproduisons pas ce script de parser ici, vous le trouverez dans l’archive ZIP téléchargeable à l’intérieur du fichier Parser_LoRaWAN.txt du dossier \Publication LoRaWAN module LoRa-E5\4 - Publication LoRaWAN\.
Si vous avez correctement suivi les instructions, votre navigateur devrait afficher à peu près ceci :
La troisième et dernière étape consiste à créer un tableau de bord (dashboard) TagoIO en suivant les instructions de cet autre tutoriel. Pour donner une idée, voici un dashboard créé en quelques minutes, constitué de trois jauges (des “windgets”) affichant les mesures de notre capteur BME280 :
NB : Vous souhaiterez peut-être faire du Downlink depuis votre dashboard TagoIO, c’est à dire envoyez des messages à vos objets. Nous n’avons pas développé cet aspect dans ce tutoriel, mais vous trouverez la procédure en suivant ce lien.
Ce tutoriel est à présent terminé !
Les possibilités offertes par TTN et TagoIO sont impressionnantes. Nous vous laissons le soin d’approfondir ces sujets que nous n’avons fait qu’effleurer par ce tutoriel.
Liens et ressources
Sur LoRa et LoRaWAN en général :
L’installation d’une passerelle TTIG est abordée par notre tutoriel dédié, qui donne aussi d’autres références.
Sur l’intégration TagoIO :
- Démarrer avec TagoIO
- Configurer TagoIO, tutoriel de TTN
- Intégration TagoIO avec TTN
- Configuration d’un Payload parser avec TagoIO
- Configuration d’un Payload parser LoRaWAN avec TagoIO
- Création d’un dashboard TagoIO
Pour une revue du module LoRa-E5 sur le blog disk91.co, c’est ici.
Concernant le module LoRa-E5, deux ressources qui expliquent aussi comment configurer un réseau LoRaWAN privé sur TTN :