Lora32 et Python – Premiers pas

Soyez patient, cet article / partie sera bientôt prêt ! Faites moi savoir votre impatience via les commentaires 😉

Je déteste programmer en Python dans de la petite robotique et des systèmes embarqués, mais comme on me l’a demandé… Je vais vous montrer comment installer et utiliser MicroPython sur des ESP32, et en particulier des Lora32 😉

Présentation

MicroPython est un microgiciel conçue par la communauté MicroPython pour les microcontrôleurs de plus de 256Ko de ROM et 16Ko de Ram (Bye bye Arduino UNO). Il offre à son utilisateur un environnement python. Sous licence open source, des versions compilées sont disponibles pour les microcontrôleurs les plus populaires comme :

  • PYBD
  • PyBoard
  • WiPy
  • ESP8266
  • ESP32

MicroPython est donc similaire à l’IDE Arduino. L’un permet de coder en Python, l’autre en C\C++. Si votre projet doit être rapidement mis en œuvre, qu’il utilise des composants connus et qu’il n’exige pas de vitesse d’exécution élevée, optez pour MicroPython. Sinon, optez pour l’IDE Arduino :

Préparation

Eléments requis

Matériel

  • PC sur Windows (testé avec v10)
  • Lora32 (ESP32 avec Lora SX1276 868-915MHz et écran SSD1306)
  • Câble micro-usb

Logiciel

  • Python 3.x (testé avec v3.7.4)
    • plugin esptool
    • plugin adafruit-ampy
  • Atom IDE ou extension Visual Studio Code
    • plugin Pymakr
  • MicroPython pour Esp32 (testé avec v1.11)
    • librairie Lora
    • librairie SSD1306
    • librairie MQTT (optionnel)

Préparation de Python sur PC

  1. Téléchargez et installez Python 3.x
  2. Ouvrez l’invite de commandes Windows (CMD ou PowerShell)
  3. Tapez pip install adafruit-ampy (internet requis)
  4. Tapez pip install esptool (internet requis)
Si une des étapes échoue :
– Vérifiez que le dossier d’installation Python soit dans le « Path »
– Vérifier que python ne soit pas bloqué par le pare-feu
– Redémarrez le PC

Installation de MicroPython sur Lora32

  1. Téléchargez la dernière version MicroPython pour ESP32 !
  2. Branchez le Lora32 sur votre PC
  3. Repérez le n° du port com dans le Gestionnaire de Périphériques
  4. Tapez esptool.py --port COMx erase_flash
  5. Tapez esptool.py --chip esp32 --port COMx write_flash -z 0x1000 C:\chemin\micropython.bin
Si votre carte n’est pas reconnue, recherchez son pilote
(pour moi : Silicon Labs CP210x USB to UART Bridge)
Dans les étapes 4 et 5 :
– Remplacez COMx par celui du Lora32 (ex : COM5)
– Remplacez C:\chemin\micropython.bin par le chemin d’accès de MicroPython

Préparation de Pymakr pour la liaison PC <> Lora32

  1. Téléchargez et installez ATOM
  2. Branchez le Lora32 sur votre PC
  3. Repérez le nom lié au port com dans le Gestionnaire de Périphériques (ex : Silicon Labs CP210x ... )
  4. Dans ATOM > Install a package : installez Pymakr (internet requis)
  5. Dans Settings > Global Settings > Autoconnect comport manufacturers : rentrez le début du nom repéré plus tôt précédé par une virgule et un espace (ex : , Silicon Labs )

Votre carte devrait être automatiquement reconnue

ATOM et Visual Studio Code permettent, si le plugin correspondant existe, de coder dans le langage et l’environnement de son choix.

Installation des librairies sur Lora32

L’installation des librairies passe par la création d’un projet sur ATOM, c’est à dire la création d’un simple dossier dans lequel on pose nos fichiers python (.py) :

  • Le fichier d’amorçage (boot.py, non obligatoire)
  • Le fichier principal (main.py, non obligatoire)
  • Les librairies (en plus de celles déjà incluses dans MicroPython)

On utilise ensuite la commande upload de Pymakr pour téléverser les fichiers.py du dossier (et de ses sous-dossiers) dans la Lora32. Nous utiliserons ici les librairies dont les sources sont :

La procédure est simple :

  1. Téléchargez, puis décompressez mon pack librairies (ou créez le votre à partir des sources ci-dessus)
  2. ATOM > File > Add Project Folder : Ajoutez le dossier racine des librairies (ex : Project_Lora32)
  3. Branchez la Lora32, vérifiez qu’elle est bien reconnue par ATOM
  4. Cliquez sur upload
Des librairies plus complètes et détaillées existent certainement. j’ai juste choisi les premières qui fonctionnaient dans mon cas 😉

Premiers essais

Les exemples de codes ci-dessous sont à mettre dans le main.py (fichier vide dans le pack), puis à téléverser dans la Lora32 (commande upload de Pymakr). Les codes Lora Sender et Receiver demandent 2 cartes Lora32 pour être testées. Amusez-vous bien 🙂

Pour utiliser l’écran OLED avec la Lora32 Heltec, il vous faut une résistance de Pull-Up (Pour moi : 330 ohms) entre l’alimentation (3.3V) et la broche 4 (SDA)
Dans la librairie ssd1306_i2c.py, la fréquence de la liaison I2C sur la Lora32 a été montée à 700 000 Hz (au lieu de 400 000 Hz)
Ne mettez pas de while true: dans main.py, sauf si vous voulez planter le terminal de commandes du Lora32, et être forcé à réinstaller MicroPython sur la carte. Utilisez les interruptions (pas testé) ou les Threads (voir codes) à la place 😉
ClignotementEcran OLEDLora SenderLora ReceiverWiFiMQTT
from machine import Pin
import _thread
import time

print("Hello World")

def testThread():
    pin_led = Pin(2, Pin.OUT)
    while True:
        pin_led.value(not pin_led.value())
        time.sleep(0.5)

_thread.start_new_thread(testThread, ())
from uPySensors.ssd1306_i2c import Display
import _thread
import time

print("Hello World")

display = Display()
display.show_text_wrap("Hi Moon")

def testThread():
    n = 0
    while True:
        display.show_text_wrap("Hi Moon " + str(n))
        n = n + 1
        time.sleep(0.5)

_thread.start_new_thread(testThread, ())
import config_lora
import _thread
from sx127x import SX127x
from time import sleep
from uPySensors.ssd1306_i2c import Display
from controller_esp32 import ESP32Controller

print("Hello World")

# Variables Lora
controller = ESP32Controller()
lora = controller.add_transceiver(SX127x(name = 'LoRa'),
                                  pin_id_ss = ESP32Controller.PIN_ID_FOR_LORA_SS,
                                  pin_id_RxDone = ESP32Controller.PIN_ID_FOR_LORA_DIO0)

# Fonction Lora
def sendThread():
    counter = 0
    print("LoRa Sender")
    display = Display()

    while True:
        payload = 'Hello ({0})'.format(counter)
        print("Sending packet: \n{}\n".format(payload))
        display.show_text_wrap("{0} RSSI: {1}".format(payload, lora.packetRssi()))
        lora.println(payload)

        counter += 1
        sleep(5)

# Lancement Lora
_thread.start_new_thread(sendThread, ())
import config_lora
import _thread
from sx127x import SX127x
from uPySensors.ssd1306_i2c import Display
from controller_esp32 import ESP32Controller

print("Hello World")

# Variables Lora
controller = ESP32Controller()
lora = controller.add_transceiver(SX127x(name = 'LoRa'),
                                  pin_id_ss = ESP32Controller.PIN_ID_FOR_LORA_SS,
                                  pin_id_RxDone = ESP32Controller.PIN_ID_FOR_LORA_DIO0)

# Fonction Lora
def receiveThread():
    display = Display()
    print("LoRa Receiver")
    display.show_text_wrap("LoRa Receiver")

    while True:
        if lora.receivedPacket():
            lora.blink_led()

            try:
                payload = lora.read_payload()
                display.show_text_wrap("{0} RSSI: {1}".format(payload.decode(), lora.packetRssi()))
                print("*** Received message ***\n{}".format(payload.decode()))

            except Exception as e:
                print(e)
                display.show_text("RSSI: {}\n".format(lora.packetRssi()), 10, 10)
                print("with RSSI: {}\n".format(lora.packetRssi))

# Lancement Lora
_thread.start_new_thread(receiveThread, ())
import network

print("Hello World")

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print(wlan.scan())

# Modifier SSID et mdp
wlan.connect(b'ssid', b'mdp') 
from umqttsimple import MQTTClient
import machine
import ubinascii
import network
import _thread
import time

print("Hello World")

# Connexion WiFi
print("Connexion WiFi")

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
print(wlan.scan())
wlan.connect(b'ssid', b'mdp')

# Attente connexion WiFi
print("Attente 10s")
time.sleep(10)

# Parametres connexion MQTT
mqtt_server = b'ip_serveur'
topic_sub = b'notification'
topic_pub = b'hello'

# Fonctions connexion MQTT
client_id = ubinascii.hexlify(machine.unique_id())

def sub_cb(topic, msg):
    print((topic, msg))

def connect_and_subscribe():
    client = MQTTClient(client_id, mqtt_server)
    client.set_callback(sub_cb)
    client.connect()
    client.subscribe(topic_sub)
    print('Connected to %s MQTT broker, subscribed to %s topic' % (mqtt_server, topic_sub))
    return client

# Connexion MQTT
print("Connexion MQTT")
client = connect_and_subscribe()

def mqttThread():
    message_interval = 5
    last_message = 0
    counter = 0
    while True:
        client.check_msg()
        if (time.time() - last_message) > message_interval:
            msg = b'Hello #%d' % counter
            client.publish(topic_pub, msg)
            last_message = time.time()
            counter += 1

_thread.start_new_thread(mqttThread, ())

Sources

Votez cet article :

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Laisser un commentaire