MQTT – enc28j60 and Arduino (22)

by luca
10 comments

Being a comics fan, I couldn’t resist publishing a crossover between my “famous” tutorial about using the enc28j60 driver with Arduino and the fresh new tutorial about the MQTT protocol.

So, after having introduced the MQTT protocol and explained how to use mosquitto, today I’ll show you how to send data to an MQTT broker using the enc28j60 ethernet controller.

Libraries

We’re going to use the PubSubClient library by Nick O’Leary to “talk” with our MQTT broker (mosquitto). You can install the library using the Library Manager in the Arduino IDE (Sketch menu – Include Library – Manage Libraries…):

mqtt-arduino01

The library I chose is based on the Ethernet Client API of Arduino, usually available if you use the “official” ethernet chip (W5100). I’ve already blogged about the UIPEthernet library that allows to use sketches and libraries designed for the W5100 chip also with the enc28j60 one. After having installed also this library in the IDE, you’re ready to write your first MQTT sketch…

For this tutorial I decided to connect to the Arduino a temperature (and humidity sensor): the DHT11. I’m going to use the DHT sensor library by Adafruit to read values from that sensor, this library too can be installed through the Library Manager.

mqtt-arduino03

Sketch

The full sketch is available in my Github’s repository.

Let’s see the most important lines of code. After having included the required libraries, the sketch defines some constants, like the topic to send data to, the identifier of the MQTT client, the interval between two transmissions and the configuration of the sensor:

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

then it configures the MAC address of the network interface and the IP address of the MQTT broker (= the IP address of the PC where mosquitto runs on):

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

the MQTT client is configured passing the Ethernet client to be used and the server (and its port) to connect to:

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

in the main loop() the sketch checks is the interval between two transmissions is passed; if so it reads the new temperature value and sends it to the broker:

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

it’s very important to call the loop() command of the MQTT Client frequently to let it process the different incoming packets and commands:

mqttClient.loop();
every tot seconds, the sketch reads the temperature, displays it on the serial terminal and sends the value to the broker. The library returns a float value, it’s therefore required to convert it in string before sending (using the dtostrf command):
float t = dht.readTemperature();
Serial.print("Temperature: ");
Serial.println(t);
 
if(mqttClient.connect(CLIENT_ID)) {
  mqttClient.publish(TOPIC, dtostrf(t, 6, 2, msgBuffer));
}

Test

Before running the sketch, first you have to start mosquitto on your PC. Open a second command prompt and run mosquitto_sub to subscribe the temperature topic:

mosquitto_sub.exe -t temperature

if you now run the sketch, you should be able to see the temperature values sent to the broker and, from this one, to the subscriber:

mqtt-arduino02

Related Posts

10 comments

Vincenzo Monday July 31st, 2017 - 03:56 PM

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 Wednesday August 2nd, 2017 - 09:11 AM

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

Reply
Vincenzo Thursday October 5th, 2017 - 06:29 PM

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 Wednesday August 30th, 2017 - 10:27 PM

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 Thursday September 7th, 2017 - 01:39 PM

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 Wednesday September 13th, 2017 - 12:24 AM

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 Monday September 18th, 2017 - 12:03 AM

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 Monday September 18th, 2017 - 10:19 AM

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

Reply
Simone Thursday November 23rd, 2017 - 12:43 AM

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 Saturday November 25th, 2017 - 02:51 PM

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

Leave a Reply to luca Cancel Reply

five + nine =