MQTT – enc28j60 e Arduino (22)

by luca
10 comments

Da appassionato di fumetti, non potevo non pubblicare un crossover tra il mio “storico” tutorial sull’uso del controller enc28j60 con Arduino e il nuovo tutorial sul protocollo MQTT.

Ecco quindi che, dopo aver introdotto il protocollo MQTT e spiegato l’uso di mosquitto, oggi vediamo come inviare dati ad un broker MQTT tramite il controller ethernet enc28j60.

Librerie

Utilizzeremo la libreria PubSubClient di Nick O’Leary per “parlare” con il nostro broker MQTT (mosquitto). La libreria può essere installata direttamente dal Library Manager di Arduino (menu Sketch – Include Library – Manage Libraries…):

mqtt-arduino01

La libreria scelta si basa sulla API Ethernet Client di Arduino, normalmente disponibile se si utilizza il chip ethernet “ufficiale” (W5100). Già in passato vi ho però parlato della libreria UIPEthernet che rende compatibili sketch e librerie scritte per tale chip anche per il chip enc28j60. Installiamo quindi anche questa libreria all’interno dell’IDE di Arduino e siamo pronti per scrivere il nostro sketch…

Infine per questo tutorial ho pensato di collegare un sensore di temperatura (e umidità) ad Arduino; il sensore scelto è il DHT11. Per leggere i valori dal sensore, utilizzeremo la libreria DHT sensor library di Adafruit, anch’essa installabile tramite il Library Manager.

mqtt-arduino03

Sketch

Ho pubblicato lo sketch completo nel mio repository Github.

Vediamo le parti principali. Dopo aver incluso le librerie, definiamo alcune costanti, tra le quali il topic al quale invieremo i dati, l’identificativo del nostro client MQTT, l’intervallo di invio dati e la configurazione del sensore:

#define CLIENT_ID       "ArduinoMQTT"
#define TOPIC           "temperature"
#define PUBLISH_DELAY   5000
#define DHTPIN          3
#define DHTTYPE         DHT11

configuriamo quindi il MAC address dell’interfaccia di rete di Arduino e l’indirizzo IP del broker MQTT (= l’indirizzo del computer sul quale è in esecuzione mosquitto):

uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};
IPAddress mqttServer(192,168,1,4);

la configurazione del client MQTT avviene indicando l’Ethernet client da utilizzare e il server (e la relativa porta) a cui connettersi:

mqttClient.setClient(ethClient);
mqttClient.setServer(mqttServer, 1883);
Serial.println(F("MQTT client configured"));

all’interno del loop() controlliamo se è trascorso l’intervallo di tempo tra una misurazione e la successiva, in caso affermativo leggiamo il nuovo valore di temperatura e inviamolo al broker:

if(millis() - previousMillis > PUBLISH_DELAY) {
  sendData();
  previousMillis = millis();
}

molto importante chiamare frequentemente il comando loop() dell’oggetto MQTT Client, in modo che questo possa processare i vari pacchetti in ingresso:

mqttClient.loop();
ogni tot secondi, lo sketch legge la temperatura, la visualizza e la invia al broker. Il valore di temperatura restituito dalla libreria è di tipo float, è quindi necessario convertirlo in stringa (usando il comando dtostrf):
float t = dht.readTemperature();
Serial.print("Temperature: ");
Serial.println(t);
 
if(mqttClient.connect(CLIENT_ID)) {
  mqttClient.publish(TOPIC, dtostrf(t, 6, 2, msgBuffer));
}

Test

Per provare lo sketch, dobbiamo per prima cosa eseguire mosquitto sul nostro PC. Apriamo inoltre un secondo prompt dei comandi e lanciamo mosquitto_sub per sottoscrivere il topic temperature:

mosquitto_sub.exe -t temperature

Se ora eseguiamo lo sketch, dovremmo vedere i valori di temperatura inviati al broker e da questi al sottoscrittore:

mqtt-arduino02

Related Posts

10 comments

Vincenzo 31 luglio 2017 - 15:56

Salve scusa mi rendo conto che il post è un po vecchiotto ma volevo chiedere se c’è un modo di sfruttare il protocollo mqtt senza lo shield ethernet, ho letto un po in giro e ho trovato la libreria per arduino SerialIp, ma è una libreria del 2010, volevo sapere se andava bene per arduino due, e se è una libreria valida.

Grazie

Reply
luca 2 agosto 2017 - 09:11

Ciao Vincenzo, la libreria SerialIP funziona ma richiede un PC collegato ad Arduino… non l’ho provata con Arduino Due

Reply
Vincenzo 5 ottobre 2017 - 18:29

Scusate se rispondo solo ora ma sono stato fuori casa per lavoro, si lo che ci vuole un pc infatti pensavo di usarlo con un raspberry collegato tramite la seriale e quindi il raspi avrebbe fatto da gateway ip.

Pensi che sia possibile, e sarebbe facile da mettere su?

Grazie

Reply
Cristian 30 agosto 2017 - 22:27

Buona sera Luca, per prima cosa vorrei farti i complimenti, spero che sei consapevole che hai la migliore guida di tutto il web sull mqtt e arduino.

Ho un piccolo problema con questo sketch:

nel monitor seriale tutto ok

nel promp dove eseguo mosquitto sembra tutto ok

1504127457: Opening ipv6 listen socket on port 1883.
1504127457: Opening ipv4 listen socket on port 1883.
1504127497: New connection from ::1 on port 1883.
1504127497: New client connected from ::1 as mosqsub|14864-Hp-Cristi (c1, k60).
1504127497: Sending CONNACK to mosqsub|14864-Hp-Cristi (0, 0)
1504127497: Received SUBSCRIBE from mosqsub|14864-Hp-Cristi
1504127497: temp (QoS 0)
1504127497: mosqsub|14864-Hp-Cristi 0 temp
1504127497: Sending SUBACK to mosqsub|14864-Hp-Cristi
1504127557: Received PINGREQ from mosqsub|14864-Hp-Cristi
1504127557: Sending PINGRESP to mosqsub|14864-Hp-Cristi

ma nel promp dove eseguo il sub non ricevo nessun valore

Riesci ad aiutarmi.
Grazie in anticipo

Reply
luca 7 settembre 2017 - 13:39

Cristian, dai logs sembra che Arduino non stia spedendo nulla… vedi infatti che il sub si collega (“new client connected as mosqsub…”). Lo sketch che output ti da?

Reply
Cristian 13 settembre 2017 - 00:24

Buona sera Luca, questo è il log da seriale arduino:
MQTT Arduino Demo

MQTT Arduino Demo
Ethernet configured via DHCP
Ip address: 192.168.1.102

MQTT client configured
Dht sensor initialized
Ready to send data
la serie delle letture.

Io utilizzo la ethernet shield e non il modulo enc28j60, può cambiare qualcosa?

Ho notato che l’ip segnato sul log di arduino è lo stesso del server dove è in funzione mosquitto, ma dovrebbe essere l’ip preso con il dhcp giusto?

Grazie mille

Reply
Cristian 18 settembre 2017 - 00:03

Buona sera Luca, ho trovato il problema…i FIREWALL…se attivi su windows, bloccano, giustamente, le connessioni alla porta 1883.

Ora funziona tutto.

Grazie
Sei davvero un grande.

Reply
luca 18 settembre 2017 - 10:19

ottimo, grazie a te per aver condiviso la soluzione al tuo problema!

Reply
Simone 23 novembre 2017 - 00:43

Buonasera Luca,

innanzitutto complimenti per il blog!
Sto provando ad utilizzare MQTT su un Arduino Nano e uno shield basato su ENC28J60. Nessun problema in fase di publish mentre continuo ad avere problemi nella lettura dei messaggi sul topic.
La callback viene correttamente scatenata con il topic valorizzato come mi aspetto mentre il valore della variabile “length” continua ad essere sempre 0, quindi payload vuoto.
Ho fatto vari test ma nulla.

Qualche consiglio?

P.S. Sto utilizzando PubSubClient e UIPEthernet.

Grazie mille in anticipo.

Reply
luca 25 novembre 2017 - 14:51

ciao Simone, molto strano… non ho mai avuto problemi a “leggere” un topic con quella libreria. Hai provato l’esempio incluso? Anche questo ti da sempre length=0?

Reply

Rispondi a Vincenzo Cancel Reply

diciannove − 2 =