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

venerdì 5 novembre 2021

Come creare un flusso di dati con ESP32

 Dopo aver realizzato le esperienze con ModBus ed ESP32 descritte nel precedente post, avere cioè creato un device che in funzione Master interroga dei device Slave con il protocollo MobBus attraverso un collegamento seriale, si presenta il problema di trasmettere questi dati da qualche parte per poterli utilizzare, magari su Dashboard intelligenti.

Photo by Jorge Ramirez on Unsplash

Come fare?

La prima cosa che ho pensato è quella di rendere possibile la trasmissione dei dati raccolti attraverso una connessione ad un server in Cloud. I sistemi di  connessione più noti sono la classica GET o la sorella maggiore POST. La differenza tra i due metodi è molto semplice, la GET trasmette i dati aggiungendoli direttamente in chiaro , all'indirizzo di chiamata ( tipo : http//ilsitoRicevente.it?id=111&dato1=222)

Il metodo POST invece non passa i parametri direttamente nell'indirizzo, ma li allega come file e li trasmette a parte all'indirizzo del server ricevente. Questo metodo è più sicuro perchè è più difficile intercettare i dati così trasmessi e quindi viene usato quando è importante la privacy e l'integrità del dato.

Per costruire la chiamata POST al mio server utilizzo la libreria  urequest già presente nella configurazione di base del Micropython installata sul ESP32, quindi basta importarla nel programma.

Qui di seguito il programma di base che ho impostato per inviare i dai con una chiamata POST .


import urequests as requests

import ujson

url = "https://iot.sottosopraweb.com/register.php"


header = {'api_key': '***LA MIA API KEY****',

           'Content-Type': 'application/json'}


data = {"ser":"777", "t1": "22", "t2": "23", "ai": "24", "ah": "25"}

data = ujson.dumps(data)

r = requests.post(url, data=data, headers=header)

print(r.text)

Dopo aver importato le librerie  necessarie, costruisco l'header della chiamata, a cui aggiungo il codice ApiKey che servirà come chiave per far accettare il pacchetto al server. costruisco la variabile data , passo la variabile data alla libreria ujson per formattare il testo in modo "digeribile" dal sistema ricevitore ed in finale creo la request (faccio la chiamata al server) e mi stampo la risposta da parte del server.

 

Spero di essere stato utile a qualcuno 
TecnoGeppetto

sabato 23 gennaio 2021

ESP32 gestione di striscia Led indirizzabile Neopixel WS2812

 I miei test sul sistema MicroPython ed ESP32 vanno avanti di gran lena, oggi ho completato il montaggio di un semplice circuito con un ESP32 ed una barretta di Led WS2812 molto comoda e facilmente inseribile nei vari circuiti che possiamo costruire "sulla scrivania".

Ho montato il circuito come da schema qui sotto, ma ho avuto dei problemi allo startup del ESP, che "sente" il GPIO basso, e si mette in Dounload mode, cioe' pronto a ricevere il firmware, e non entra in posizione lavoro. Quindi ho deciso di utilizzare un'altra porta (ce ne sono tante!) per evitare l'inconveniente


La verisone di ESP sulla quale sto lavorando, probabilmente ha dei problemi di circuito, infatti non funziona il Pin dei 5V (il Vin, cioe' il pin che e' collegato all'alimentazione proveniente  dalla USB, di conseguenza sono sato costretto a collegarmi alla 3,3V per alimentare la barretta di Led ( siamo un po' sotto il limite della minima tensione ammessa, che e' di 4V, ma dai testi funziona ugualmente!!). Con questa configurazione pero' devo stare attento ad accendere i Led mai alla massima potenza, in quanto assorbirebbero tropo per il componente stabilizzatore di tensione installato sulla scheda (infatti , se funzionasse!, sarebbe certamente meglio usare l'alimentazione diretta dalla USB per alimentare la barretta di LED, questo modo che ho scelto io, passa attraverso lo stabilizzatore di tensione che si occupa di alimentare il microcontrollore ed il wifi, quindi ha gia' il suo bel da fare!)

Di seguito il codice uploadato sull ESP che fa accendere i led di un colorino arancione uno per volta fino ad accendere tutta la barretta, poi fa il percorso inverso e spenge tutti uno alla volta. Fa' questo di continuo, fino a che non riceve un break (Ctrl-C) da terminale.

from machine import Pin
from neopixel import NeoPixel
import time

pin = Pin(16, Pin.OUT)   # set GPIO16 to output to drive NeoPixels
np = NeoPixel(pin, 8)   # create NeoPixel driver on GPIO0 for 8 pixels
while True:
    for i in range(8):
        np[i] = (2555)      # set the first pixel to orange
        np.write()              # write data to all pixels
        time.sleep_ms(500)
    for i in range(80, -1):
        np[i-1] = (000)      # set the first pixel to orange
        np.write()              # write data to all pixels
        time.sleep_ms(500)


Buon divertimento 

TecnoGeppetto




giovedì 31 dicembre 2020

Client MQTT subscriber e publisher per linux - Raspberry Pi

 A seguire gli esperimenti di questi giorni, oggi mi sono dedicato alla configurazione su linux di un sistema per leggere i messaggi inviati dal sensore. Ho cercato un client MQTT che potesse essere utilizzato da linea di comando ed ho trovato e configurato questo che adesso decrivero'.


Ho trovato il progetto Eclipse che fa al caso mio, hanno sviluppato una libreria disponibile su github per la gestione delle comunicazioni con un broker MQTT che si chiama paho che risolve la maggior parte dei problemi e consente con 4 righe di codice  di ottenere cio' di cui ho bisogno.

I passi necessari per far funzionare tutto sono questi:

su linux ( io per praticita' utilizzo una shell linux in WSL su windows, perche' in questo periodo sto usando un pc con windows) creo la mia direttory di progetto che ho chiamato mqtt_client 


quindi entro nella cartella appena creata con 


quindi creo il file che conterra' il codice del programma MQTT client subscriber


edito il contenuto del file con i dati del mio broker MQTT pubblico  scelto.

file  subscribe.py:

# subscribe.py
import paho.mqtt.client as mqtt

def on_connect(client, userdata, flags, rc):
    print(f"Connected with result code {rc}")
    # subscribe, which need to put into on_connect
    # if reconnect after losing the connection with the broker, it will continue to subscribe to the raspberry/topic topic
    client.subscribe("TecnoGeppetto/topic")

# the callback function, it will be triggered when receiving messages
def on_message(client, userdata, msg):
    print(f"{msg.topic} {msg.payload}")
    
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

# set the will message, when the system is powered off, or the network is interrupted abnormally, it will send the will message to other clients
client.will_set('TecnoGeppetto/status', b'{"status": "Off"}')

# create connection, the three parameters are broker address, broker port number, and keep-alive time respectively
client.connect("broker.emqx.io", 1883, 60)

# set the network loop blocking, it will not actively end the program before calling disconnect() or the program crash
client.loop_forever()

Naturalmente per far funzionare tutto sulla distribuzione linux che ho scelto e' presente python 3.xx, se non lo fosse e' necessario installarlo  assieme a pip3 che servira' per installare la libreria di cui si fa       l' import nel codice.

sudo apt install python3

poi

pip3 install paho-mqtt

A questo punto per far girare il client in ricezione sui topic scelti nel codice ( nel caso qui pubblicato TecnoGeppetto/topic  , basta chiamare 



Nel caso di problemi di connesisone il sistema rende un codice di errore, questa di seguito e' la legenda dei possibili codici

0: connection succeeded
1: connection failed - incorrect protocol version
2: connection failed - invalid client identifier
3: connection failed - the broker is not available
4: connection failed - wrong username or password
5: connection failed - unauthorized
6-255: undefined
If it is other issues, you can check the network situation, or check whether `paho-mqtt` has been installed.


Naturalmente il topic da scegliere deve essere lo stesso sul quale trasmette il sensore, in modo da poter regolarmente ricevere il messaggio trasmesso ogni volta dal sensore.


Buon divertimento 

TecnoGeppetto




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




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

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

mercoledì 22 giugno 2016

ESP8266 i comandi AT

L' ESP8266 appena scartato dalla confezione originale dovrebbe avere gia' caricato il firmware di default che consente di comunicare attraverso semplici comandi AT Hayes compatibili, quelli dei vecchi modem telefonici, per capirsi. I vecchi appassionati della prima ora di internet se li ricordenranno sicuramente.

 Girovagando in rete ho trovato questo link dove vengono riepilogati tutti i comandi in maniera dettagliata.

Room-15

Riporto qui di seguito un copia ed incolla piu' significativo, rimandando al link sopra per un approfondimento  maggiore

I comandi AT riconosciuti dal modulo ESP8266


Index of all known AT commands

Basic WiFI layer TCPIP Layer
AT AT+CWMODE AT+CIPSTATUS
AT+RST AT+CWJAP AT+CIPSTART
AT+GMR AT+CWLAP AT+CIPSEND
AT+GSLP AT+CWQAP AT+CIPCLOSE
ATE AT+CWSAP AT+CIFSR
AT+CWLIF AT+CIPMUX
AT+CWDHCP AT+CIPSERVER
AT+CIPSTAMAC AT+CIPMODE
AT+CIPAPMAC AT+CIPSTO
AT+CIPSTA AT+CIUPDATE
AT+CIPAP +IPD

Line termination

ESP8266 expects  or CarriageReturn and LineFeed at the end of each command, but just ; seems to work too.

Command variants

Each command can have up to 4 variants changing the function of it. You can chose between them by appending one of four possible values to the end of the root command itself. These four appendices can have the following values "",=,"?",=?
Type Example Description
Test AT+CIPSTART=? Query the range of values (So far only AT+CWMODE=? uses it)
Query AT+CMD? Returns the current value of the parameter.
Set AT+CMD=Parameter Set the value of user-defined parameters in commands and run.
Execute AT+CMD Runs commands with no user-defined parameters.
Note:
  • Not all AT commands support all 4 variants.
  • [] = default value, not required or may not appear.
  • String values require double quotation marks, for example: AT+CWSAP="ESP756190","21030826",1,4.
  • Baud rate = 115200
  • AT instruction ends with “\r\n”

Commands

AT - Test AT startup

Variant Command Response Function
Execute AT OK Test if AT system works correctly

AT+RST - Restart module

Variant Command Response Function
Execute AT+RST OK Reset the module

ESP-01 Output after reset:

 ets Jan  8 2013,rst cause:4, boot mode:(3,7)

wdt reset
load 0x40100000, len 24444, room 16
tail 12
chksum 0xe0
ho 0 tail 12 room 4
load 0x3ffe8000, len 3168, room 12
tail 4
chksum 0x93
load 0x3ffe8c60, len 4956, room 4
tail 8
chksum 0xbd
csum 0xbd

ready

ESP-12 Output after reset:

\0x04B1\0x85 \0xff\0x13:'\0xe0;\0xcc;!G\0xfa\0x11\0xa9R\0xc6\0x83\0x01\0xd9\0x81
[Vendor:www.ai-thinker.com Version:0.9.2.4]

ready

AT+GMR - View version info

Variant Command Response Function
Execute AT+GMR version, OK Print firmware version
Parameters:
  • version: firmware version number
ESP-01 output:
00160901
ESP-12 output:
0018000902-AI03

AT+GSLP - Enter deep-sleep mode

Variant Command Response Function
set AT+GSLP=time time OK Enter deep sleep mode for time milliseconds
parameters:
  • time: Time to sleep in milliseconds
Example:
AT+GSLP=1500
Note:
Hardware has to support deep-sleep wake up (Reset pin has to be High).

ATE - Enable / Disable echo

Variant Command Response Function
Execute ATE0 OK Disable echo (Doesn’t send back received command)
Execute ATE1 OK Enable echo (Sends back received command before response)
Note:
I haven’t had any luck with this command yet. Both ATE0 and ATE1 return no this fun.
ATE returns OK
This changed with ESP-12 where the command functions exactly as expected!

AT+CWMODE - WIFI mode(station, AP, station + AP)

Variant Command Response Function
Test AT+CWMODE=? +CWMODE:(1-3) OK List valid modes
Query AT+CWMODE? +CWMODE:mode OK Query AP’s info which is connect by ESP8266.
Execute AT+CWMODE=mode OK Set AP’s info which will be connect by ESP8266.
Parameters:
  • mode: An integer designating the mode of operation either 1, 2, or 3.
    1 = Station mode (client)
    2 = AP mode (host)
    3 = AP + Station mode (Yes, ESP8266 has a dual mode!)
Notes:
ESP-12 came configured as host with ssid set to ESP_A0A3F2, no password, channel 1 You can use AT+CWSAP? to find the current settings.

AT+CWJAP - Connect to AP

Variant Command Response Function
Query AT+CWJAP? + CWJAP:ssid OK Prints the SSID of Access Point ESP8266 is connected to.
Execute AT+CWJAP=ssid,pwd OK Commands ESP8266 to connect a SSID with supplied password.
Parameters:
  • ssid:String, AP’s SSID
  • pwd:String, not longer than 64 characters
Example:
AT+CWJAP="my-test-wifi","1234test"  
Example AT+CWJAP?
+CWJAP:"my-test-wifi"  

AT+CWLAP - Lists available APs

Variant Command Response Function
Set AT+CWLAP=ssid,mac,ch +CWLAP:ecn,ssid,rssi,mac OK Search available APs with specific conditions.
Execute AT+CWLAP AT+CWLAP:ecn,ssid,rssi,mac OK Lists available Access Points.
Parameters:
  • ecn:
    • 0 = OPEN
    • 1 = WEP
    • 2 = WPA_PSK
    • 3 = WPA2_PSK
    • 4 = WPA_WPA2_PSK
  • ssid: String, SSID of AP
  • rssi: signal strength
  • mac: String, MAC address
Note:
On ESP-01 I have had no luck with the set version of this command (AT+CWLAP=...). If you know what it does please let me know.
On ESP-12, the Set version of the command allows to see if a certain SSID, with certain MAC on certain channel exists. If it doesit is returned as one line of the Execute version of this command.
Example AT+CWLAP:
+CWLAP:(3,"CVBJB",-71,"f8:e4:fb:5b:a9:5a",1)
+CWLAP:(3,"HT_00d02d638ac3",-90,"04:f0:21:0f:1f:61",1)
+CWLAP:(3,"CLDRM",-69,"22:c9:d0:1a:f6:54",1)
+CWLAP:(2,"AllSaints",-88,"c4:01:7c:3b:08:48",1)
+CWLAP:(0,"AllSaints-Guest",-83,"c4:01:7c:7b:08:48",1)
+CWLAP:(0,"AllSaints-Guest",-83,"c4:01:7c:7b:05:08",6)
+CWLAP:(4,"C7FU24",-27,"e8:94:f6:90:f9:d7",6)
+CWLAP:(2,"AllSaints",-82,"c4:01:7c:3b:05:08",6)
+CWLAP:(3,"QGJTL",-87,"f8:e4:fb:b5:6b:b4",6)
+CWLAP:(4,"50EFA8",-78,"74:44:01:50:ef:a7",6)
+CWLAP:(0,"optimumwifi",-78,"76:44:01:50:ef:a8",6)
+CWLAP:(3,"BHQH4",-95,"18:1b:eb:1a:af:5b",6)
+CWLAP:(3,"NETGEAR49",-86,"84:1b:5e:e0:28:03",7)
+CWLAP:(3,"ngHub_319332NW00047",-56,"20:e5:2a:79:b1:2f",11)
+CWLAP:(3,"BFZR4",-73,"18:1b:eb:1d:c3:91",11)
+CWLAP:(1,"5FFVL",-82,"00:26:b8:b5:c0:f2",11)
+CWLAP:(3,"59G6D",-77,"00:7f:28:6d:91:7b",11)
+CWLAP:(3,"N16FU",-53,"20:cf:30:ce:60:fe",11)
+CWLAP:(3,"ITS",-82,"90:72:40:21:5f:76",11)
+CWLAP:(3,"ITS",-79,"24:a2:e1:f0:04:e4",11)
Example AT+CWLAP="N16FU","20:cf:30:ce:60:fe",11:
+CWLAP:(3,"N16FU",-53,"20:cf:30:ce:60:fe",11)

AT+CWQAP - Disconnect from AP

Variant Command Response Function
Execute AT+CWQAP OK Disconnect ESP8266 from the AP is currently connected to.
Note:
After running this command, if you run AT+CWJAP? it still shows the AP you were connected to before.

AT+CWSAP - Configuration of softAP mode

Variant Command Response Function
Query AT+CWSAP? +CWSAP:ssid,pwd,ch,ecn OK Query configuration of ESP8266 softAP mode.
Set AT+CWSAP=ssid,pwd,ch,ecn OK Set configuration of softAP mode.
Parameters:
  • ssid: String, ESP8266’s softAP SSID
  • pwd: String, Password, no longer than 64 characters
  • ch: channel id
  • ecn:
    • 0 = OPEN
    • 2 = WPA_PSK
    • 3 = WPA2_PSK
    • 4 = WPA_WPA2_PSK
Example
AT+CWSAP="esp_123","1234test",5,3
AT+CWSAP? => +CWSAP:"esp_123","1234test",5,3

AT+CWLIF - List clients connected to ESP8266 softAP

Variant Command Response Function
Execute AT+CWLIF [ip,other] OK List information on of connected clients.
Parameters:
ip: IP address of a client connected to the ESP8266 softAP other: Other info, look at example. I don’t know what it means yet.
Example (ESP-01):
AT+CWLIF

192.168.4.100,3fff50b4:3fff50ba:3fff50c0:3fff50c6:3fff50cc:3fff50d2

OK
Example (ESP-12):
AT+CWLIF

192.168.4.100,c0:ee:fb:25:33:ec

OK
I ran the command after connecting to the ESP8266 with my cellphone.

AT+CWDHCP - Enable/Disable DHCP

Variant Command Response Function
Set AT+CWDHCP=mode,en OK Enable or disable DHCP for selected mode
Parameters:
  • mode:
    • 0 : set ESP8266 as a softAP
    • 1 : set ESP8266 as a station
    • 2 : set both ESP8266 to both softAP and a station
  • en:
    • 0 : Enable DHCP
    • 1 : Disable DHCP
Note:
This command doesn’t seem to work on firmware 00160901 (ESP-01) nor 0018000902-AI03 (ESP-12).

AT+CIPSTAMAC - Set MAC address of ESP8266 station

Variant Command Response Function
Query AT+CIPSTAMAC? +CIPSTAMAC:mac OK Print current MAC ESP8266’s address.
Execute AT+CIPSTAMAC=mac OK Set ESP8266’s MAC address.
Parameters:
  • mac: String, MAC address of the ESP8266 station.
Example:
AT+CIPSTAMAC="18:aa:35:97:d4:7b"
Note:
This command doesn’t seem to work on firmware 00160901

AT+CIPAPMAC - Set MAC address of ESP8266 softAP

Variant Command Response Function
Query AT+CIPAPMAC? +CIPAPMAC:mac OK Get MAC address of ESP8266 softAP.
Execute AT+CIPAPMAC=mac OK Set mac of ESP8266 softAP.
Parameters:
  • mac: String, MAC address of the ESP8266 softAP.
Example:
AT+CIPAPMAC=”2c:aa:35:97:d4:7b”
Note:
This command doesn’t seem to work on firmware 00160901

AT+CIPSTA - Set IP address of ESP8266 station

Variant Command Response Function
Query AT+CIPSTA? +CIPSTA:ip OK Get IP address of ESP8266 station.
Execute AT+CIPSTA=ip OK Set ip addr of ESP8266 station.
Parameters:
  • ip: String, ip address of the ESP8266 station.
Example:
AT+CIPSTA=”192.168.101.108”
Note:
This command doesn’t seem to work on firmware 00160901

AT+CIPAP - Set ip address of ESP8266 softAP

Variant Command Response Function
Query AT+CIPAP? +CIPAP:ip OK Get ip address of ESP8266 softAP.
Execute AT+CIPAP=ip OK Set ip addr of ESP8266 softAP.
Parameters:
  • ip: String, ip address of ESP8266 softAP.
Example:
AT+CIPAP="192.168.5.1"
Note:
This command doesn’t seem to work on firmware 00160901

AT+CIPSTATUS - Information about connection

Variant Command Response Function
Test AT+CIPSTATUS=? OK
Execute AT+CIPSTATUS STATUS:status +CIPSTATUS:id,type,addr,port,tetype OK Get information about connection.
Parameters:
  • status
    • 2: Got IP
    • 3: Connected
    • 4: Disconnected
  • id: id of the connection (0~4), for multi-connect
  • type: String, “TCP” or “UDP”
  • addr: String, IP address.
  • port: port number
  • tetype
    • 0 = ESP8266 runs as a client
    • 1 = ESP8266 runs as a server
Note:
On ESP-01 this command returns STATUS:1 instead (no extra info, but status changes) On 0018000902-AI03 this command returns STATUS:2 instead (no extra info, but status changes)

AT+CIPSTART - Establish TCP connection or register UDP port and start a connection

Variant Command Response Function
Set AT+CIPSTART=type,addr,port OK Start a connection as client. (Single connection mode)
Set AT+CIPSTART=id,type,addr,port OK Start a connection as client. (Multiple connection mode)
Test AT+CIPSTART=? [+CIPSTART:(id)(“type”),(“ip address”),(port)] OK List possible command variations)
Parameters:
  • id: 0-4, id of connection
  • type: String, “TCP” or “UDP”
  • addr: String, remote IP
  • port: String, remote port

AT+CIPSEND - Send data

Variant Command Response Function
Test AT+CIPSEND=? OK
Set AT+CIPSEND=length SEND OK Set length of the data that will be sent. For normal send (single connection).
Set AT+CIPSEND=id,length SEND OK Set length of the data that will be sent. For normal send (multiple connection).
Execute AT+CIPSEND Send data. For unvarnished transmission mode.

Normal Mode

Parameters:
  • id: ID no. of transmit connection
  • length: data length, MAX 2048 bytes

Unvarnished Transmission Mode

Wrap return “>” after execute command. Enters unvarnished transmission, 20ms interval between each packet, maximum 2048 bytes per packet. When single packet containing “+++” is received, it returns to command mode.

AT+CIPCLOSE - Close TCP or UDP connection

Variant Command Response Function
Test AT+CIPCLOSE=? OK
Set AT+CIPCLOSE=id OK Close TCP or UDP connection.For multiply connection mode
Execute AT+CIPCLOSE OK Close TCP or UDP connection.For single connection mode
Parameters:
  • id: ID no. of connection to close, when id=5, all connections will be closed.
Note:
In server mode, id = 5 has no effect!

AT+CIFSR - Get local IP address

Variant Command Response Function
Test AT+CIFSR=? OK
Execute AT+CIFSR +CIFSR:ip OK Get local IP address.
Parameters:
  • ip: IP address of the ESP8266 as an client.
Example AT+CIFSR:
10.101.10.134

AT+CIPMUX - Enable multiple connections or not

Variant Command Response Function
Set AT+CIPMUX=mode OK Enable / disable multiplex mode (up to 4 conenctions)
Query AT+CIPMUX? +CIPMUX:mode OK Print current multiplex mode.
Parameters:
  • mode:
    • 0: Single connection
    • 1: Multiple connections (MAX 4)
NOTE:
This mode can only be changed after all connections are disconnected. If server is started, reboot is required.

AT+CIPSERVER - Configure as server

Variant Command Response Function
Set AT+CIPSERVER=mode[,port] OK Configure ESP8266 as server
Parameters:
  • mode:
  • 0: Delete server (need to follow by restart)
  • 1: Create server
  • port: port number, default is 333
NOTE:
  1. Server can only be created when AT+CIPMUX=1
  2. Server monitor will automatically be created when Server is created.
  3. When a client is connected to the server, it will take up one connection,be gave an id.

AT+CIPMODE - Set transfer mode

Variant Command Response Function
Query AT+CIPMODE? +CIPMODE:mode OK Set transfer mode,normal or transparent transmission.
Set AT+CIPMODE=mode OK Set transfer mode,normal or transparent transmission.
Parameters:
  • mode:
  • 0: normal mode
  • 1: unvarnished transmission mode

AT+CIPSTO - Set server timeout

Variant Command Response Function
Query AT+CIPSTO? +CIPSTO:time Query server timeout.
Set AT+CIPSTO=time OK Set server timeout.
Parameters:
  • time: server timeout, range 0~7200 seconds

AT+CIUPDATE - update through network

!!! Don’t run this unless you know what you’re doing !!!

### !!! It will likely brick your device !!! Attempts to self-update from the internet.
Variant Command Response Function
Execute AT+CIUPDATE +CIPUPDATE:n OK Start update through network
Parameters:
-n:
- 1: found server
- 2: connect server
- 3: got edition
- 4: start update
Example:
AT+CIUPDATE

+CIUPDATE: 1
+CIUPDATE: 2
+CIUPDATE: 3
+CIUPDATE: 4

\0x02\0x8cl\0x8el\0x8e\0x1cp\0x0c\0x8c\0xf2nn\0xee\0x00l\0x8c\0x8el`
\0x02\0x90\0x12\0x12nnl\0x8cl`\0x02\0x0e\0x02nr\0x8e\0x92\0x92n\0x0c\0x0c
\0x02\0x8c\0x92`\0x02`
\0xf2n\0x0c\0x0c\0x0c\0x9e\0xe0b\0x82nl\0x8c\0x0c\0x8c
\0xf2nn\0xee\0x00\0x0c\0x8e\0x0elp\0xf2n\0xe0\0x10\0x02\0x0c
\0x0cr\0x8c\0x9c\0x9c\0xe2\0xe0\0x0c\0x0c\0x0c
\0x0cb\0x0cn\0xe2|\0x02\0xec\0xecl\0x8c\0x0cb\0x8c\0xf2nn
...forever

lunedì 4 gennaio 2016

Recenti battaglie con ESP8266


Dopo una lunga inattività blogghereccia, provo a ricominciare a documentare alcune delle esperienze che ho fatto in questo lungo periodo di assenza dai social.
Una delle ultime fide alle quali ho dedicato  del tempo, è stata quella di domare la scheda ESP8266-01, il modulo riportato in foto qui a fianco.
Grande come un francobollo (forse meno!) la schedina monta un microcontrollore a 40Mhz di tutto rispetto e consente (dopo che sarai riuscito a domarla!!) di avere semplicemente una connessione internet ovunque tu abbia una seriale disponibile. Infatti puo' essere collegata a qualsiasi periferica o microprocessore, o computer, soltanto collegando GND TX ed RX, in questo modo si potra' accedere ad internet attraverso il WiFi standard per la quale questa meravigliosa scheda è stata progettata.

Purtroppo chi ha commissionato il progetto, doveva avere necessita' soltanto di un paio di PIN del microprocessore, magari e' stata utilizzata come interruttore remoto, oppure come controllo remoto della temperatura. Sta di fatto che, sebbene il microcontrollore ESP8266 che è il chip contenuto nella scheda, abbia a disposizione molti PIN, la circuiteria ne mette a disposizione solo 2, GPIO0 e GPIO2.

Sebbene molti blog riportano tanti esperimenti e circuiti dedicati, ho trovato in pochissimi Blog la descrizione  dettagliata di come fare la programmazione della schedina; Questo fatto mi fa pensare che la maggior parte dei blasonati blog in giro per la rete, in effetti sia soltanto online per produrre contenuti a cottimo, senza effettivamente testare quanto descritto nei tutorial pubblicati. Il lavoro maggiore per chi ha la passione del Maker, è proprio quello di mediare le tante ciarlonerie che si trovano in giro per ottenere il risultato desiderato.
Dico questo perchè dopo aver letto una diecina di blog e tutorial in giro, in nessuno ho trovato la semplice descrizione di come fare per programmare VERAMENTE la scheda. La maggior parte ti descrive come ricevere i dati, ma se prima non la programmi....c'è poco da ricevere!!!

Quindi come si fa?

Questo di seguito e' il circuito da montare per poter programmare la schedina. Vanno montati due pulsanti (ma si puo' fare anche facendo corto tra due fili, tanto serve soltanto per la fase di programmazione, se sei bravo col codice e ti funziona tutto alla "prima botta" puoi anche montare tutto volante e fare contatto tra due fili)
Per mettere il microcontrollore in modalità programmazione si deve mettere a GND in PIN  GPIO0 durante la fase di accensione oppure durante il Reset (secondo pulsante).
Quindi collegato il modulino e preparato lo sketch sulla IDE di Arduino, basta premere e tenere premuto il pulsante P1 (GPIO0 - GND) e poi premere P2 (RST - GND) - Rilasciare P2 e in fine  rilasciare P1 ma solo  dopo iniziato l'upload del binario

Questa notizia, direi quasi banale, e' fondamentale da conoscere per poter inserire il proprio codice nel microcontrollore, ma, controllate voi, nessuno lo spiega chiaramente, quindi per poterlo fare ho perduto giorni di prove senza risultato.
Adesso sappiamo come fare a inserire il codice nel modulo.
Alla prossima puntata, un esempio di come utilizzare il modulino in un progettino.
Ciao