martedì 29 dicembre 2020

ESP8266 e MQTT con MicroPython, connessione e primi vagiti

 Dopo aver domato i mostriciattoli ESP8266  ed ESP32 come visto nei post precedenti, oggi mi sono cimentato nella pubblicazione di dati con il protocollo MQTT.
Il sistema lo avevo testato per la prima volta durante un corso che ho fatto quest'anno, in sonstanza e' molto semplice, un server dove gira il software Mosquitto, riceve messaggi da un nodo e li "gira" a tutti i nodi che sono in ricezione su un determinato "topic".

Il sistema che ho testato si compone di due ESP8266, uno che si preoccupa di inviare un messaggio su uno specifico "topic" ed ascolta invece un topic diverso attraverso il quale ricevera' la notifica di ricezione dall'altro nodo (un suo fratello ESP8266). L'altro ovviamente, ricevera' sul canale di trasmissione del primo, e  trasmettera' su quello di ricezione del primo. in maniera di avere un sistema che trasmette un messaggio su un canale e riceve ok di ricezione su un altro. 


Quindi il codice per il primo ESP8266 sara' il seguente:

boot.py

# TecnoGeppetto
# Sistema MQTT con esp8266 / esp32
#
# ESP#1
# 
import time
from umqttsimple import MQTTClient
import ubinascii
import machine
import micropython
import network
import esp
esp.osdebug(None)
import gc
gc.collect()
import webrepl


ssid = "XXXXXXXXXXXXXXXX"
password = "XXXXXXXXXXXXXXX"
mqtt_server = 'XXXXXXXXXXXXXXX'
#EXAMPLE IP ADDRESS
#mqtt_server = '192.168.1.144'
client_id = ubinascii.hexlify(machine.unique_id())
topic_sub = b'TecnoGeppetto/notifica'
topic_pub = b'TecnoGeppetto/ciao'

last_message = 0
message_interval = 5
counter = 0

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())
webrepl.start()
    

main.py

# ESP #1

def sub_cb(topic, msg):
  print((topic, msg))
  if topic == b'TecnoGeppetto/notifica' and msg == b'received':
    print('ESP received hello message')

def connect_and_subscribe():
  global client_id, mqtt_server, topic_sub
  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

def restart_and_reconnect():
  print('Failed to connect to MQTT broker. Reconnecting...')
  time.sleep(10)
  machine.reset()

try:
  client = connect_and_subscribe()
except OSError as e:
  restart_and_reconnect()

while True:
  try:
    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
  except OSError as e:
    restart_and_reconnect()


Questi sopra sono i file di cui fare upload sul primo ESP8266 nei quali va sostituito al posto delle XXXXXX i dati per accedere al proprio router per il collegamento ad internet ed il numero IP del broker MQTT. ( in un altro progetto che pubblichero' piu' avanti, un server MQTT fatto in casa con Raspberry).
Come detto sopra, il primo device crea una connessione con il broker, sottoscrive un topic sul quale rimane in ascolto, nel caso in esempio : TecnoGeppetto/notifica 
Quando sono trascorsi 5 secondi, pubblica sul topic  TecnoGeppetto/ciao   un  saluto "Hello"

L'altro ESP8266 avra' invece questo software :


boot.py

# ESP#2

import time
from umqttsimple import MQTTClient
import ubinascii
import machine
import micropython
import network
import esp
esp.osdebug(None)
import gc
gc.collect()

ssid = "XXXXXXXXXXXX"
password = "XXXXXXXXXX"
mqtt_server = 'xxxxxxxxxxxx'
#EXAMPLE IP ADDRESS
#mqtt_server = '192.168.1.144'
client_id = ubinascii.hexlify(machine.unique_id())
topic_sub = b'TecnoGeppetto/ciao'
topic_pub = b'TecnoGeppetto/notifica'

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())


main.py

# ESP#2

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

def connect_and_subscribe():
  global client_id, mqtt_server, topic_sub
  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

def restart_and_reconnect():
  print('Failed to connect to MQTT broker. Reconnecting...')
  time.sleep(10)
  machine.reset()

try:
  client = connect_and_subscribe()
except OSError as e:
  restart_and_reconnect()

while True:
  try:
    new_message = client.check_msg()
    if new_message != 'None':
      client.publish(topic_pub, b'received')
    time.sleep(1)
  except OSError as e:
    restart_and_reconnect()

Che apre una connessione ad internet via router, si connette al broker MQTT, si mette in ascolto del topic :  TecnoGeppetto/ciao      e quando riceve il "saluto" inviato dal primo, pubblica sul topic:  TecnoGeppetto/notifica       la conferma di ricezione.

Elaborato dal progetto originale che puoi trovare qui 

Buon divertimento
TecnoGeppetto

Nessun commento: