Skip to main content

An MQTT-powered display using an Arduino Ethernet and LCD

A simple example using the MQTT Arduino library and a 16x2 LCD.

 

title

In a previous post we used a temperature sensor and wireless transmitter with a Raspberry Pi and Node-RED to build a heating control system. In another post we went on to use MQTT to allow us to scale across multiple devices, with a Node-RED system and a separate temperature sensor node.

In this post we will use an Arduino Ethernet with an LCD screen to expand on this system, subscribing to an MQTT topic and displaying the messages as they are published to it from Node-RED. This allows monitoring of the messages on our topics without using a desktop computer.

We will assume that you already have an MQTT broker running with a device publishing messages on a topic. If you don't already have this, see the aforementioned posts for details.

Hardware Used

Setting up the hardware

We will use the 16x2 character LCD module that comes bundled with the Arduino Starter Kit, though these and similar displays can also be purchased separately.

First ensure that the Arduino is powered down. Then use a breadboard and jumper wires to connect the LCD module as per the diagram below:

title

LCD Pin

Connected to

1

GND

2

5v

3

10k potentiometer

4

Arduino pin 8

5

GND

6

Arduino pin 9

7

 

8

 

9

 

10

 

11

Arduino pin 5

12

Arduino pin 7

13

Arduino pin 3

14

Arduino pin 2

15

220 ohm resistor

16

GND

 

Note that if you are using a different LCD module you will need to refer to the relevant datasheet to ensure correct wiring.

Next create a new sketch in the Arduino IDE and paste in the code below:

//include the library that simplifies use of the LCD module

#include

//define the pins the LCD module is connected to

LiquidCrystal lcd(8, 9, 5, 7, 3, 2);

void setup() {

//things here run once at the beginning

lcd.begin(16, 2);

lcd.print("hello, world");

}

void loop() {

//things here run in a loop

//this sets the cursor position on the LCD, column 0, line 1

lcd.setCursor(0,1);

//this will print the time elapsed since startup to the LCD display

lcd.print(millis() / 1000);

}

Now connect the USB to serial adapter and Arduino Ethernet to your computer and upload the sketch. The IDE will ask you to save the sketch before uploading. Once the sketch is uploaded you should see the LCD powered up and displaying our test messages. If you do not see anything, try turning the potentiometer, this changes the contrast on the LCD display.

title

MQTT on the Arduino

To use the Arduino as an MQTT client we will need to make use of a third party library which can be downloaded from here. Next copy the 'PubSubClient' directory into your Arduino libraries folder (the location of which is determined by the operating system you are using).

Restart the Arduino IDE and check to see if the library has installed correctly: look in File>Examples and you should see 'PubSubClient' at the bottom. If so, open a new sketch and paste in the code below:

/*

Basic MQTT example with Authentication

- connects to an MQTT server, providing username and password

- publishes "hello world" to the topic "outTopic"

- subscribes to the topic "inTopic"

This sketch is modified to print the topic payload to Serial for debugging

*/

#include

#include

#include

// Update these with values suitable for your network.

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xA1, 0x95 }; // MAC address of your Arduino

byte server[] = { 10, 0, 10, 21 }; // IP address of your MQTT broker

byte ip[] = { 10, 0, 10, 149 }; // IP address of your Arduino

void callback(char* topic, byte* payload, unsigned int length) {

Serial.print("Payload: ");

Serial.write(payload, length);

Serial.println();

}

EthernetClient ethClient;

PubSubClient client(server, 1883, callback, ethClient);

void setup()

{

Serial.begin(9600);

Ethernet.begin(mac, ip);

//print out the IP address

Serial.print("IP = ");

Serial.println(Ethernet.localIP());

if (client.connect("arduinoClient", "USERNAME", "PASSWORD")) {

client.publish("outTopic","hello world");

client.subscribe("inTopic");

}

}

void loop()

{

client.loop();

}

You will need to modify the following in the above sketch:

  • MAC address

  • IP address of the MQTT broker

  • IP address of Arduino

  • User name and password for MQTT broker

Ensure your Arduino is connected to the network and upload the sketch.

Next head over to your MQTT broker on the same network (we are using Mosquitto running on a Raspberry Pi with Node-RED that we built in this post).

Start a new Node-RED flow and drag in an MQTT input node. Double-click to edit it and add the following details:

  • Topic: 'outTopic'

  • username and password

Close the editing window and drag in a debug node. Connect the two nodes together and deploy the flow. Now look at the debug panel on the right hand side and reset your Arduino. When it restarts you should see the message 'hello world' appear in the debug panel.

title

Now let's see if we aresubscribing correctly. Drag in an MQTT output node to your flow and edit the following details:

  • Topic: 'inTopic'

  • username and password

Close the editing window and drag in an inject node. We will use the default timestamp payload for testing. Connect the two nodes and deploy the flow. Head back to the Arduino IDE and open the Serial Monitor. Then go back to your flow and click the button on the inject node. You should see the timestamp message appear in the Serial Monitor window. If not, things to check include:

  • Ensure the Arduino is connected to your computer with a USB to Serial adapter

  • Check the username and passwords match in both the Arduino code and Node-RED flow.

  • Check that the topics match.

  • Check that the Serial Monitor is set at the correct baud rate and port.

title

Displaying MQTT messages

Now that we have tested each part of our system we can put everything together. We know that our LCD display works and thatthe Arduino can subscribe to an MQTT topic. Our existing Node-RED flow is already reading temperature data from a sensor. We can build on this by adding an MQTT output node and publishing the temperature data to a new topic, 'officeTemp'. We will also add an inject node and connect it to the MQTT output node to help with testing. Once added to the workspace and configured we can deploy the flow.

title

Now we can write a sketch for the Arduino that subscribes to an MQTT topic and displays the messages on the LCD screen. We will also publish a message to an MQTT topic when the Arduino connects to our broker to say that the LCD monitor is online. See below for our code:

/*

Code based on "Basic MQTT example with Authentication" sketch

- connects to an MQTT server, providing username and password

- subscribes to the topic "officeTemp"

- prints the topic payload to Serial for debugging

- displays messages in topic on LCD screen

- publishes 'online' message to topic "node1"

*/

#include

#include

#include

//include the library that simplifies use of the LCD module

#include

//define the pins the LCD module is connected to

LiquidCrystal lcd(8, 9, 5, 7, 3, 2);

// Update these with values suitable for your network

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xA1, 0x95 };

byte server[] = { 10, 0, 10, 21 };

byte ip[] = { 10, 0, 10, 149 };

void callback(char* topic, byte* payload, unsigned int length) {

Serial.print("Payload: ");

Serial.write(payload, length);

Serial.println();

//clear LCD screen

lcd.clear();

//set cursor position on the LCD at column 0, line 0 then display Office Temp

lcd.setCursor(0,0);

lcd.print("Office Temp");

//set cursor position on the LCD at column 0, line 1

lcd.setCursor(0,1);

//write the payload to the LCD display and add ' C' after it

lcd.write(payload, length);

lcd.print(" C");

}

EthernetClient ethClient;

PubSubClient client(server, 1883, callback, ethClient);

void setup()

{

Serial.begin(9600);

Ethernet.begin(mac, ip);

//Print Arduino IP address to serial for debugging

Serial.print("IP = ");

Serial.println(Ethernet.localIP());

if (client.connect("arduinoClient", "pi", "bilberry")) {

client.publish("node1","LCD Display Online");

client.subscribe("officeTemp");

}

lcd.begin(16, 2);

}

void loop()

{

client.loop();

}

As before ensure that you update the network, topic and login details in the above sketch.

Upload the code to your Arduino. Note that nothing will be displayed on the LCD screen until it receives the first MQTT message. We can send a test message by heading to our Node-RED flow and clicking the button on the inject node connected to our MQTT output node. We can also open the Serial Monitor in the Arduino IDE to check the messages we are receiving.

title

Final Thoughts

We now have an Arduino-based display connected to our network that can subscribe to MQTT topics and display the content of messages. Though useful as it is, ways this could be expanded upon include:

  • Adding a temperature sensor to the Arduino and publishing remote readings to an MQTT topic, which our central Node-RED system can then process.

  • Adding a potentiometer and publishing readings to a topic, which Node-RED subscribes to and uses to configure the thermostatset point.

  • Adding a switch to the Arduino, reading it's state, publishing it to a topic and using it as a master override for the heating control.



maker, hacker, doer
DesignSpark Electrical Logolinkedin