Visualizzazione post con etichetta DHT11. Mostra tutti i post
Visualizzazione post con etichetta DHT11. Mostra tutti i post

mercoledì 30 dicembre 2020

ESP32 ESP8266 pubblica da DHT11 temperatura ed umidita' su un broker MQTT

 Conseguenza naturale degli ultimi due progetti (gli ultimi due post pubblicati!) e' quella di pubblicare su di un broker MQTT i dati rilevati da un sensore DHT11 di temperatura ed umidita' rilevata.
Il circuito e' come il precedente: 

  • Un ESP32 od un ESP8266 (il codice funziona su entrambi)
  • un sensore DHT11
  • alimentazione 3,3volt o 5 volt 
  • un broker MQTT disponibile


Collegato il sensore al Pin 14 del ESP8266 (quello contrassegnato con le lettere D5 sul circuito) (attenzione per ESP32 in pin e' diverso), non resta altro che creare la connessione con il router per l'accesso ad internet.
Creare la connessione con il broker.
Effettuare la lettura del dato dal sensore.
Inviare la lettura come contenuto del messaggio verso il broker MQTT.

Il sistema si mette in ascolto su un topic di notifica, costruito ad hoc per confermare al device la corretta lettura del dato dal lato del ricevitore ( mi immagino un sistema che pubblica su un display il valore della temperatura ricevuta, oppure una dashboard che riceve piu' sensori e ne grafica i dati ricevuti). Nel caso che la conferma di ricezione non arrivi per oltre 1 ora, il sistema si resetta e ricarica il firmware dall'inizio, ricominciando con nuove connessioni ecc....

boot.py:

# TecnoGeppetto
# Sistema MQTT con esp8266 / esp32
# Legge la temperatura da DHT11 e invia a sever Mosquitto
# 
# 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
import dht
from machine import Pin

ssid = "XXXXXXXXXXXXXXXXXXXXXX"
password = "XXXXXXXXXXXXXX"
mqtt_server = 'XXXXXXXXXXXXXXXXXXX'
#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/temp'

sensor = dht.DHT11(Pin(14)) #il pin al quale e' collegato il sensore DHT11

last_message = 0
message_interval = 5   #intervallo tra i messaggi
last_start = time.time()
start_interval = 3600  # intervallo tra le conferme di ricezione da parte del sistema
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'OK':
    print('ESP Ha ricevuto la Temperatura!')
    last_start = time.time()                 #azzero contatore del reset

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()
  
def get_temp():             #legge la temperatura dal sensore DHT11
  sensor.measure()
  temp = sensor.temperature()
  hum = sensor.humidity()
  return [temp,hum]


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:
      temp=get_temp()
      msg = b"N. "+str(counter)+" Temperatura. "+str(temp[0])+" Umidita. "+str(temp[1])
      client.publish(topic_pub, msg)
      last_message = time.time()
      counter += 1
    if (time.time() - last_start) > start_interval:     #se e' passato piu di start_interval dall ultima conferma di ricezione
      restart_and_reconnect()                             #resetto la scheda e riconnetto
  except OSError as e:
    restart_and_reconnect()



Con il codice sopra il sensore comincia a pubblicare i valori letti dal sensore DHT11 sul topic TecnoGeppetto/temp, e si mette in ascolto sul topic TecnoGeppetto/notifica 

Buon divertimento
TecnoGeppetto




lunedì 28 dicembre 2020

DHT11 ESP8266 NEOPIXEL e Micropython

 Ho ripreso in mano il mio ESP8266 per approfondirne la conoscenza. Nell'ultimo post ho imparato a caricare il Micropython ed a collegare il mio ESP8266 da remoto con WebREPL.


In questo modo e' possibile caricare i file di programma nel file system del ESP8266, in modo da poterli poi far "girare" chiamandoli direttamente da termionale o madandoli in esecuzione direttamente al boot, utilizzando il file di sistema boot.py.

Infatti il MicroPython, gia' dalla sua istallazione prevede il file boot.py che in automatico la macchina chiama ad ogni reboot, quindi e' facile poter far partire tutti i programmi che vogliamo opportunamente impostando solamente  quest'ultimo file.


Avevo in un cassetto un ESP8266 superstite da alcuni altri passati esperimenti, al quale era gia' collegato e funzionante una barretta di 8 led Neopixel ed un sensore DHT11.

Niente di meglio per fare amicizia con il sistema Micropython.

Ho iniziato ad impostare la rete in modo fisso, in maniera che ad ogni reboot l'ESP si colleghi in automatico con il router di casa, semplicemente copiando le istruzioni necessarie nel file  boot.py (le stesse che abbiamo visto nel post di ieri).

Fatto questo e reso automatica la partenza del sistema WebREPL come visto ieri, impostando la password.

Ho iniziato a caricare tramite WebREPL il file di un semplice programma che legge la temperatura dal sensore e la stampa sulla consolle.

TEMP.PY :

#questo programma legge la temperatura e l'umidita' dal sensore DHT11 
#collegato al Pin 14 del ESP8266 (il pin contrassegnato con D5)

from machine import Pin
#from time import sleep
import dht 
#sensor = dht.DHT22(Pin(14))
sensor = dht.DHT11(Pin(14))

def get_temp():
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()
    return [temp,hum]


def leggi_temp():
    sensor.measure()
    temp = sensor.temperature()
    hum = sensor.humidity()
    print('Temperature: %3.1f C' %temp)
    print('Humidity: %3.1f %%' %hum)
    


Poi ho caricato un secondo file leds.py che gestira' i leds della barretta di Neopixel con a bordo il famoso led WS2812B.

LEDS.PY :

# questo programma scrive colori su neopixel ws2812B
# i neopixel sono collegati al Pin 5 che e' marcato D1 sulla scheda esp8266

import machine, neopixel
from time import sleep
import temp
n = 8 #numero dei pixel disponibili
p = 5 #pin sul quale sono collegati i led

np = neopixel.NeoPixel(machine.Pin(p), n)

def temp_leds():
    lista = temp.get_temp()
    if lista[0] <= 16:
        np[0] = (0,0,5)
        np[1] = (0,0,0)
        np[2] = (0,0,0)
        np[3] = (0,0,0)
        np[4] = (0,0,0)
        np[5] = (0,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 17:
        np[0] = (0,0,5)
        np[1] = (0,0,5)
        np[2] = (0,0,0)
        np[3] = (0,0,0)
        np[4] = (0,0,0)
        np[5] = (0,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 18:
        np[0] = (0,5,3)
        np[1] = (0,5,3)
        np[2] = (0,5,0)
        np[3] = (0,0,0)
        np[4] = (0,0,0)
        np[5] = (0,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 19:
        np[0] = (0,5,3)
        np[1] = (0,5,3)
        np[2] = (0,5,0)
        np[3] = (0,5,0)
        np[4] = (0,0,0)
        np[5] = (0,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 20:
        np[0] = (0,5,0)
        np[1] = (0,5,0)
        np[2] = (0,5,0)
        np[3] = (0,5,0)
        np[4] = (5,5,0)
        np[5] = (0,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 21:
        np[0] = (0,5,0)
        np[1] = (0,5,0)
        np[2] = (0,5,0)
        np[3] = (0,5,0)
        np[4] = (5,5,0)
        np[5] = (5,0,0)
        np[6] = (0,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 22:
        np[0] = (0,5,0)
        np[1] = (0,5,0)
        np[2] = (0,5,0)
        np[3] = (0,5,0)
        np[4] = (5,5,0)
        np[5] = (5,0,0)
        np[6] = (5,0,0)
        np[7] = (0,0,0)
        np.write()
    elif lista[0] == 23:
        np[0] = (0,5,0)
        np[1] = (0,5,0)
        np[2] = (0,5,0)
        np[3] = (0,5,0)
        np[4] = (5,5,0)
        np[5] = (5,0,0)
        np[6] = (5,0,0)
        np[7] = (5,0,0)
        np.write()
    else:
        np[0] = (3,0,0)
        np[1] = (3,0,0)
        np[2] = (3,0,0)
        np[3] = (3,0,0)
        np[4] = (5,0,0)
        np[5] = (5,0,0)
        np[6] = (5,0,0)
        np[7] = (5,0,0)
        np.write()
def smooth_red():
    for led in range(8):
        for i in range(50):
            np[led] = (i, 0, 0)
            np.write()
            sleep(0.025)

def spengi_leds():
    for i in range(8):
        np[i] = (0, 0, 0)
    np.write()

def smooth_green():
    for led in range(8):
        for i in range(50):
            np[led] = (0, i, 0)
            np.write()
            sleep(0.025)

def smooth_blu():
    for led in range(8):
        for i in range(50):
            np[led] = (0, i, 0)
            np.write()
            sleep(0.025)
        

Inizialmente ho fatto amicizia con i colori (attenzione a non far partire alla massima intensita' tutti i led assieme che potrebbe essere dannoso per l'alimentazione del computer al quale e' collegato l'ESP, a causa del  troppo assorbimento - circa 60 mA per ogni led)

Infine li ho inseriti nel file di boot.py per far si che possano funzionare gia' dal reboot:

Il sistema cosi impostato, legge la temperatura una sola volta all'accensione, e in funzione del valore letto, accende i led di colore blu se la temperatura e' al di sotto dei 16 - 17 gradi
di colore verde per valori tra i 17 ed i 20 gradi e di rosso se la temperatura supera i 20 gradi.
I led si accendono in modo che la scala sia "parlante" in funzione dell'aumento della temperatura.
Cioe' < 16 gradi solo il primo led - poi via via fino a 24 gradi con tutti e 8 i led accesi.

E' ovvio che il tutto e' fatto per test e per fare conoscenza! Per fare un device intelligente, la temperatura va letta ad iintervalli costanti ed aggiornata la scla dei led in conseguenza. Ma non era questo lo scopo dei miei test di oggi (comunque bastano altre due righe di codice per farlo!)


BOOT.PY


# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
import webrepl
import network
import temp
import leds
sta_if = network.WLAN(network.STA_IF)
sta_if.connect("XXXXXXXXXXXXXXXXXX","XXXXXXXXXXX") # Connect to an AP
print("LA mia connessione e' attiva e questo e' il mio indirizzo: ", sta_if.ifconfig())
webrepl.start()
gc.collect()
temp.leggi_temp()

leds.temp_leds()


Oggi sono arrivato fino qui!
A domani (forse ) per la prossima puntata.
TecnoGeppetto