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 😉
Sommaire
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 :
MicroPython
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)
- Heltec Lora32 V2 (prévoir câble et résistance)
- Wemos Lilygo Lora32 (Attention, écran fragile !)
- 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
- Téléchargez et installez Python 3.x
- Ouvrez l’invite de commandes Windows (CMD ou PowerShell)
- Tapez
pip install adafruit-ampy(internet requis) - Tapez
pip install esptool(internet requis)
Installation de MicroPython sur Lora32
- Téléchargez la dernière version MicroPython pour ESP32 !
- Branchez le Lora32 sur votre PC
- Repérez le n° du port com dans le Gestionnaire de Périphériques
- Tapez
esptool.py --port COMx erase_flash - Tapez
esptool.py --chip esp32 --port COMx write_flash -z 0x1000 C:\chemin\micropython.bin
Préparation de Pymakr pour la liaison PC <> Lora32
- Téléchargez et installez ATOM
- Branchez le Lora32 sur votre PC
- Repérez le nom lié au port com dans le Gestionnaire de Périphériques (ex :
Silicon Labs CP210x ...) - Dans ATOM > Install a package : installez Pymakr (internet requis)
- 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
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 :
- MQTT (optionnel) : umqttsimple (Source annexe : tutoriel)
- Lora et SSD1306 : uPyLora et uPySensors (Source annexe : tutoriel)
La procédure est simple :
- Téléchargez, puis décompressez mon pack librairies (ou créez le votre à partir des sources ci-dessus)
- ATOM > File > Add Project Folder : Ajoutez le dossier racine des librairies (ex : Project_Lora32)
- Branchez la Lora32, vérifiez qu’elle est bien reconnue par ATOM
- Cliquez sur
upload
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 🙂
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, ())