0% found this document useful (0 votes)
11 views23 pages

44IOTG Lab 5 - MQTT (2)

This document outlines Lab 5 for the Internet of Things (IoT) course at Ngee Ann Polytechnic, focusing on the MQTT protocol for communication between devices. It details the objectives, equipment needed, and preparation steps, including software installation and limitations of the ESP32 web server. The lab aims to implement a home monitoring and control system using MQTT, emphasizing the publish/subscribe model and the use of a public broker for testing purposes.

Uploaded by

danzel1585
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views23 pages

44IOTG Lab 5 - MQTT (2)

This document outlines Lab 5 for the Internet of Things (IoT) course at Ngee Ann Polytechnic, focusing on the MQTT protocol for communication between devices. It details the objectives, equipment needed, and preparation steps, including software installation and limitations of the ESP32 web server. The lab aims to implement a home monitoring and control system using MQTT, emphasizing the publish/subscribe model and the use of a public broker for testing purposes.

Uploaded by

danzel1585
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 23

Ngee Ann Polytechnic

School of Engineering
Internet of Things (IoT) 44IOTG-012628

LAB 5: Introduction to MQTT 221202a


Use cloud MQTT server for communication

Name: ____________________________________________ Lab Grp: ___________ Date: ____________


IMPORTANT:
 Show your completed PREPARATION section to your supervisor
 Complete the lab 5 quiz and any submission in BS.

OBJECTIVES
 Understand the architecture of MQTT protocol for communication
 Use MQTT library and cloud server for communicate between devices
 Test out a simple “battery-powered” sensor.
 Test and implement a simple home monitoring & control system

EQUIPMENT
You only need the kitset issued to you.
You may connect AC lamps to G1 (P15) and G2 (P32) (HIGH to on) working in parallel with LED1 and LED2.

PREPARATION
All procedures can be done at home using the kitset with home WiFi router or hotspot.
ACKNOWLEDGEMENT: We will be using HiveMQ public broker (server) to learn MQTT for IoT. They have a
set of useful learning materials, including an eBook. This labsheets use some diagrams from there.
https://www.hivemq.com/mqtt-essentials/
https://www.hivemq.com/public-mqtt-broker/ (no security used on this server)
We will use the PubSubClient library for ESP32 documented here https://pubsubclient.knolleary.net/api

1. Software Installation
Install the following before coming for the lab:
1. Install MQTT-Explorer on your laptop. Refer here https://mqtt-explorer.com/
It is “Version 0.4.0-beta1” as at 2022-11-15. Choose the portable version which can be run directly.
Run it once to make sure that it works. We will use this to simulate the ESP32 MQTT client for testing.
2. On your Android device, phone or tablet, install “IoT MQTT Panel” (Rahul Kundu) in the Play Store.
https://play.google.com/store/apps/details?id=snr.lab.iotmqttpanel.prod

https://www.snrlab.in/iot/iot-mqtt-panel-user-guide/

IOTG Lab 5 Apr 2023 Page 1 of 23


If you do not have an Android device, on your laptop install “BlueStacks 5” Android emulator from
here https://www.bluestacks.com/download.html

(We have not try version 10)


Download, install and run and make sure it works.
You would need a Google account for activation. During the activation, UNCHECK “Back up to Google
Drive” (if you miss that, it’s fine). After that, install the “IoT MQTT Panel” app from Google Play Store.
If you’ve problem with BlueStacks 5, try BlueStacks 10, or e.g. https://www.bignox.com/

2. Limitations of ESP32 Webserver & WebSocket


In the previous lab, we run a Webserver (HTTP) and WebSocket on ESP32.
 It allows a remote browser to monitor & control the LEDs (lamps).
 Locally, the LEDs can be controlled through the pushbuttons
 The LEDs statuses are sent to the browser for display in real-time thru WebSocket.
The above has these serious limitations:
 The ESP32 server has to be on all the time and is not practical for battery-powered devices that are
intended to last for, say a year without battery change.
After sending a sensor reading to the server, it goes into sleep mode to conserve power and wake up,
say after a few minutes or hours before sending another new reading.
 Unless special setup is carried out, the server is accessible only in the local network, and not from
anywhere else in the world.
The above is solved by using servers in the cloud rather than ESP32 working as a server. The
communication interface and protocols used are to be “light-weight” in terms of power consumption and
amount of data transferred.

2.1 Communication Hardware Interfaces


WiFi interface is meant for short range communication and it consumes significantly more power than
some low-power short-range communication interfaces like Bluetooth, Zigbee.
For long range communication interfaces, there are options like LoRa, Sigfox, NB-IoT.
In this lab, we will use WiFi for connectivity to access a cloud server.

2.2 Communication Software Protocols


Webserver (HTTP) and WebSocket protocols are not ideal for low data traffic and power consumption. We
will use the MQTT protocol which is commonly used in IoT applications. It runs on top of TCP/IP layer.
A comparison between HTTP and MQTT: https://www.hivemq.com/blog/mqtt-vs-http-protocols-in-iot-iiot/
Question: What are the limitations of ESP32 working as a webserver? ______________________________
_______________________________________________________________________________________

3. MQTT Model
References:
https://youtu.be/2aHV2Fn0I60
https://www.hivemq.com/blog/mqtt-essentials-part2-publish-subscribe/
IOTG Lab 5 Apr 2023 Page 2 of 23
https://www.hivemq.com/blog/mqtt-essentials-part-3-client-broker-connection-establishment/
The MQTT architecture is based on publish/subscribe model with clients connected to a broker (server).
Only 1 broker is used.

Subscribe
to topic
Publish
“temperature”
to topic
“temperature” Subscribe
to topic
“temperature”
Once setup, the broker is transparent

Publish Receive topic


“temperature” +
topic “temperature” + payload payload (data)
(data)

The MQTT commands available are CONNECT, SUBSCRIBE, PUBLISH, UNSUBSCRIBE and DISCONNECT.
A client must first do a CONNECT using a unique client ID (a name) to the broker before any
subscribe/publish. If the ID is already used by another client, connection would fail!
Any client can PUBLISH a “topic” with “payload” containing the data/message. Any client can SUBSCRIBE
to the topic to receive the data in the payload. The broker takes care of sending the published topic and
data to clients that subscribed to the topic. Once connected, the broker is transparent to the clients.
A topic is just a name that follows proper MQTT rules. Topics do not have to be predefined.
Topic examples: (“send” for publisher and “receive” for subscriber(s))
s12345678/room/status/sensor Send/receive a sensor reading; payload = “0” to “4095”
s12345678/room/status/lamp1 Send/receive lamp1 status. Payload = “1” means on, “0” off
s12345678/room/cmd/lamp1 Send/receive command to toggle lamp1; payload = “T”
The client that publishes, does not need to know who (can be multiple clients) subscribes to the topic.
The client that subscribes to a topic, does not need to know who publishes the topic.
In the design of a system (must be secured), all client ID, topics, publishers and subscribers should be
properly predefined so that all clients in the system work together properly.
NOTE: MQTT is meant for low data volume traffic communication. Avoid constantly publishing at short
intervals, e.g. every second. Typically, there is a slight delay for the subscriber to receive the topic.

3.1 Quality of Service


Reference: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels/
There are 3 levels of Quality of Service (QoS) in MQTT as below:
- QoS = 0 At most once; it is a best-effort delivery though there is no guarantee of delivery.
This is the default. For non-critical application, this should be fine.
IOTG Lab 5 Apr 2023 Page 3 of 23
- QoS = 1 At least once; subscriber may receive the topic and data more than once.
- QoS = 2 Exactly once; subscriber is guaranteed to receive it exactly once.
The higher the QoS, the higher is the overhead (complexity) in the protocol between the broker and
clients. In our lab, we only use QoS=0.

3.2 The Broker


The broker is the “middle-man” providing services to the clients. After sending published topic and data to
the subscribers (or if there’s no subscriber), the topic and data is deleted from the system, unless the topic
is published with the “retain” option which we would not cover.
Retain message references:
https://www.hivemq.com/blog/mqtt-essentials-part-8-retained-messages/
http://www.steves-internet-guide.com/mqtt-retained-messages-example/

4. MQTT Topics Rules


Reference: https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
Some rules on the topic names:
- Use UTF-8 string. We will only use ASCII codes. Spaces are allowed but should be avoided.
- It is case-sensitive. “Room” and “room” are different!
- It must have at least 1 character
- It can have 1 or more levels separated by ‘/’.

4.1 Wild Cards


For subscription, topic names to subscribe can have these two wild cards for specifying level(s).
- ‘+’ is a single level wild card that matches any name at that level
- ‘#’ is a multi-level wild card is used at the end of a topic to indicate all subsequent levels
Subscribing to topic “home/+/temperature” would match the following
- “home/room1/temperature”
- “home/kitchen/temperature”
but would not match this topic (2 levels in between)
- “home/room1/cabinet/temperature”
On the other hand, subscribing to topic “home/#” would match all of the above 3 topics.
Questions
In the MQTT model, how many MQTT broker are there? __________________
Can a client be both a publisher and a subscriber at the same time? _______________
Does the subscriber know who publish the message? ____________________
Does the publisher know who the message is sent to? ____________________
In general, the MQTT broker kept all the published message? ________________
How many QOS (Quality of Service) levels are there in the MQTT model? _________
If you cannot tolerate losing your messages which QOS do you set? ______________
MQTT topics using backward slash (‘\’) as a limiter separating topic level (T / F) __________
State the 3 basic criteria for an acceptable topic name: _________________________________________
______________________________________________________________________________________
IOTG Lab 5 Apr 2023 Page 4 of 23
Wildcards # is used to denote a part of the topic eg hou# (for topics like house, hour) (T/F) __________
Subscribing to topic “house/+/light” covers “house/room1/light”, “house/room2/light” (T/F) _________
Subscribing to topic “house/#” covers “house/room1/light”, “house/room2/temp” (T/F) _________
Subscribing to topic “house+” is not valid. Why? ___________________________________________
A publisher can use topics with wild cards (# or +) (T/F) _____________________________________

5. MQTT Broker & Clients Used


5.1 A Public Broker
We will use a free public broker: https://www.hivemq.com/public-mqtt-broker/
As this broker is public with no authentications or encryption, it has no security. Anyone can access the
topics (if they know) used in the lab. That is fine as we are learning the basics of MQTT. Broker Info:
- Broker name: broker.hivemq.com
- TCP Port: 1883

5.2 Our MQTT Clients


We will have the following clients in this lab exercise.
1. ESP32 Client
We will use the 3 LEDs (simulate 2 lamps and an LED status) and 2 PBs (lamps control) on the board. It also
regularly publishes a sensor reading. We will implement MQTT client using “PubSubClient” library.
2. Android Client - “IoT MQTT Panel” app
We will use Android “IoT MQTT Panel” app on Android (or “BlueStacks 5” Android emulator running on
laptop) to monitor and control the ESP32 unit. You are required to install it before the lab.
3. MQTT-Explorer Client on Laptop - simulate ESP32 Client for testing
You are required to install the mqtt-explorer before the lab. This is only used for testing purpose. We shall
call this PC ESP32 Client.

6. A Battery-Operated Sensor MQTT Client


We will test out a simple “battery-operated” sensor which publishes the sensor reading and then go to
deep sleep in order to save power. It wakes up after an interval to repeat the process.
MQTT Broker Android MQTT Client
ESP32 MQTT Client
Publish topic: Subscribe topic:
“s12345678/room “s12345678/room/
/status/sensor” status/sensor”
to send payload: to receive payload:
“0” to “4095” “0” to “4095”

The procedure:
 Connect to WiFi
 Connect to MQTT broker
 Publish the sensor reading
 Disconnect from MQTT broker
IOTG Lab 5 Apr 2023 Page 5 of 23
 Disconnect from WiFi
 Deep sleep for an interval to save power
 Repeat the above
This ESP32 application only publishes data. There’s no topic subscription.

6.1 MQTT Client and Topic Names Declarations


Refer to the codes in Appendix A. IMPORTANT: For the codes downloaded, you must first change “rootT”
to your student number!
It is important that the mqtt client name is unique, else there will be connection error! The topic names
must also be unique in the lab shared environment, else, you may receive data from fellow students.
Refer to the “rootT”, “mqttClientName” and a topic declarations below.
#define rootT "s12345678" // VERY IMPORTANT: change to your student number
const char *mqttClientName = "mqttClient_" rootT;
const char *topicSensor = rootT "/room/status/sensor"; // Topics to publish
The “mqttClientName” is equivalent to
const char *mqttClientName = "mqttClient_" "s12345678";
It be compiled as:
const char *mqttClientName = "mqttClient_s12345678";
The same idea applies to the topic declaration with “rootT”.

6.2 Understanding the Codes


Two different clients are used in the program, name their type and object name:
WiFiClient wifiClient, PubSubClient mqttClient
______________________________________________________________________________________
Refer to connectReportDisconnect(). What are the 3 possible errors encountered?
_____________________________________________________________________________________
The common function called by connectReportDisconnect() if any error encountered: (refer to the end of
the function) _____________________________

Assuming no error encountered, briefly describe what connectReportDisconnect() does: ______________


_____________________________________________________________________________________
_____________________________________________________________________________________
Statement used by mqttSetupBroker() to set MQTT broker (server) name & port number:
_____________________________________________
State the broker name & port number: _______________________________________________________
Statement used by mqttConnect() to connect to the MQTT broker: _________________________________
Name the statement used in publishSensor() to publish a topic and state the 2 parameters passed.
_____________________________________________________________________________________
Name the topic used to publish sensor reading: _______________________________________________
Function used in publishSensor() to convert sensor value to a string and where is the string stored:
_____________________________________________________________________

IOTG Lab 5 Apr 2023 Page 6 of 23


If an error is encountered, it is often assumed that chances of another error in the next attempt is high.
Thus, in order to conserve battery, it is common to have a longer sleep when an error is encountered. In
the program, the duration of deep sleep is stored in “deepSleepDur”, set in “connectReporttDisconnect()”:
Duration of deep sleep when no error encountered: ___________ When error encountered: __________
FRO challenge if curious, else skip: (Reference: https://cplusplus.com/reference/cstdlib/itoa/)
What is the purpose of “10” in the call to itoa() statement? Why the buf[] size is 6 (not less)? (You need to
understand C char array for string. Note the maximum possible value for sensorReading of uint16_t.)
____________________________________________________________________________________
____________________________________________________________________________________
____________________________________________________________________________________

7. A Home Monitoring & Control


7.1 System Diagram
We will implement a home remote monitoring and control system. It has two clients. The Lamps are
represented by 2 LEDs. In the lab, we can also connect 2 AC lamps to the grove connectors G1 and G2.
MQTT Broker Android MQTT Client
ESP32 MQTT Client
Sensor reading Sensor reading
Lamps status Lamps status
Remote –
monitoring
Toggle lamp Toggle lamp & control
Tell me lamp status Tell me lamps status
Home – 2 LEDs + 2 PBs local controls

7.2 The Two MQTT Clients and Their Resources


A. ESP32 Client & Resources
ESP32 is located at home accepting remote command. It sends sensor and lamp info to the remote client.
At the same time, it serves local PBs to control the lamps. Resources at ESP32:
ESP32 client Purpose
Lamp1 Red LED (parallel with P15 to control an AC lamp)
PB1 Control lamp1 (Red LED). Each press toggles the lamp & update remote client.
Sensor at A5 Read and report to remote client every 5 seconds
System Status LED Yellow LED to show system status
- Normal operation: Slow blinking
- System error: Fast blinking. Possible reasons: Error encountered during WiFi
connection, MQTT connection or MQTT publication.

B. Android MQTT Client Resources - IoT MQTT Panel


The Android Client is the remote unit that will have user Interface below:

IOTG Lab 5 Apr 2023 Page 7 of 23


Display sensor
reading

Display lamp1 Button to remotely


status control lamp1

Button to get lamps’ statuses


(if necessary)

Android Client Panel Purpose


Sensor gauge Display ESP32 analog sensor reading
Lamp1 LED Display ESP32 lamp1 status (on or off)
Lamp1 button Request ESP32 to toggle lamp1 and send back its status
Request lamps Request ESP32 to send back all lamps’ status. This is in case the display is not
statuses button showing the latest info.

7.3 Clients Topics and Payloads


In order to achieve the above, we will have these topics and payloads for ESP32 and Android clients.A.

A. ESP32 Client Topics and Payload


ESP32 client Topic Payload value & meaning
Subscribe s12345678/room/cmd/lamp1 “T” – Request to toggle lamp1; also send lamp1 status
Subscribe s12345678/room/cmd/lamps “Q” – Request for all lamps’ statuses
Publish s12345678/room/ status/lamp1 “1” – Tell IoT Panel that lamp1 is on
“0” – Tell IoT Panel that lamp1 is off
Publish s12345678/room/status/sensor “0” to “4095” - A string representing ADC reading

B. Android Client Topics and Payload


Android Topic Payload value & meaning
client
Subscribe s12345678/room/status/sensor “0” to 4095” – Sensor reading for display
Subscribe s12345678/room/status/lamp1 “1” – display lamp1 is on
“0” – displaylamp1 is off
Publish s12345678/room/cmd/lamp1 “T” – Request ESP32 to toggle lamp1 & send back its
status
Publish s12345678/room/cmd/lamps “Q” – Query ESP32 for all lamps’ statuses
This is in case displayed lamps statuses are incorrect

7.4 ESP32 Client Codes


We learned how to publish a topic with a payload in ESP32 in the previous section on “A Battery-Operated
Sensor”. Before publication, these setups must happen first:
- WiFi connection
- Setup MQTT client with broker name and port number
IOTG Lab 5 Apr 2023 Page 8 of 23
- Connect to the broker
A publish example is:
if (mqttClient.publish(topicSensor, buf)) { // publish topic with payload
return true; // publish success
}
return false; // publish failure
We will now focus on how to do subscription. Two more setup must be done:
- Subscribe to topics of interest
- Setup a callback function so that when a topic arrives, it would be called to process the topic & data
Refer to the codes in Appendix B for mqttHome sketch.

A. ESP32 Client Setup & Topics Subscribed


Refer to wifiConnToDo() which is called when WiFi is connected successfully. It calls various functions to
do setup and update variable “mqttConOK”.
What does mqttSetupBrokerNCB() do? (Refer to function itself and functions it calls. Read the comments.)
_______________________________________________________________________________________
_______________________________________________________________________________________
Name of callback function for processing topic received: ______________________________________
After a successful mqttConnect(), function called to subscribe to topics: (Note that it subscribes to 2 topics)
_______________________________________________________________________________________

B. Callback when A Subscribed Topic & Payload arrives


When a subscribed topic arrives from the broker, it would call mqttCallback(). Study the codes there.
Three parameters are received by the callback:
- String topic Refers to the topic received
- byte* data Payload – an array of 8-bit data (similar to char)
- unsigned int length The number of bytes of data in the array above
The for loop in that function builds a C++ String “payload” so that we can later use “payload == "Q"” for
String comparison. Standard C string does not allow comparison in that manner. Note that the String type
method .c_str() returns a standard C string so that we can use “%s” formatter in printf to print it.
In mqttCallback(), after comparing with the topics of interest, it calls either processCmdLamp1() or
processCmdLamps().

Name function called when processCmdLamp1() receives payload “T”: _____________________________


Name function called when processCmdLamps() receives payload “Q”: _____________________________
At the end of the lab, you will be asked to implement a Lamp2 monitoring and control.

C. The loop()
Refer to the loop(). Statement that must be called regularly in order for ESP32 MQTT client to work?
________________________________________________

CHECKPOINT 1: Show to your supervisor the completed preparation section ________________

IOTG Lab 5 Apr 2023 Page 9 of 23


PROCEDURE
There are 3 APs in the labs at 06-03. Room 2: ASUS_0603. Room 3: r060303. Room 4: r060304.
If your ESP32 has problem using the lab APs, you can use your own mobile phone hotspot. The data
traffic used in the programs is little, though is more than that for lab 4 as we need to access cloud server.
NOTE: As we will be using a cloud server, your laptop does not need to be connected to the same AP as
long as it can access to the cloud MQTT server at port 1883. This is unlike Lab 4 that uses local network.

A. Software Installed & Codes Download


1. Preparation Software installation: We assume that you had installed these software during your
preparations: MQTT-Explorer on your laptop; IoT MQTT Panel app in your Android device or
BlueStacks 5 Android emulator.
2. Download the codes used in this lab from BS.

B. Testing MQTT Broker and Clients


IMPORTANT: The given program uses “s12345678” defined in “rootT” to identify MQTT client name and
topics. Change it to your own student number. All clients in server must have a unique client name (ID),
otherwise, there will be connection error.

B.1 PC ESP32 Client setup - MQTT-Explorer Simulating ESP32 client


In this part of the lab, we will use the MQTT-explorer to simulate ESP32 client.
Refer to the preparation section “A Home Monitoring and Control” under “Clients Topics and Payloads:” >
“A. ESP32 Client Topics and Payload”
3. Start MQTT-Explorer. Click ‘+’ button at the top left to setup a new connection and follow steps
indicated, then click “ADVANCED”

1 Connections The connection


2 name “esp32”

3 broker.hivemq.com

No username required Setup topic to


subscribe
4

IOTG Lab 5 Apr 2023 Page 10 of 23


4. Subscribe to topic “sxxxxxxxx/room/cmd/lamp1” (where sxxxxxxxx is your student number). Do not
change the “MQTT Client ID”. After entering a topic, click “+ADD”. Finish with “BACK”.
Add each to
1 2 the list below
Subscribe topics
…/room/cmd/lamp1
…/room/cmd/lamps

Two topics subscribed

After two topics subscribed,


go back to main page 3

A unique ID automatically given

Click “SAVE” followed by “CONNECT”.

1 Save setup
2
Connect now

Your connection must be successful showing the following:

When no longer required,


click “DISCONNECT” to go
Connected to the broker. back to main page
Received topic subscribed will appear in
this left window with its payload (data).

Enter the topic you


want to publish here

Use “raw” to publish the topic payload

Ener payload data here


before clicking “PUBLISH”

We’ve just setup MQTT-Explorer to simulate the ESP32. It subscribes to the topics of interest.
We’ll next setup the Android client.

IOTG Lab 5 Apr 2023 Page 11 of 23


B.2 Android Client Setup: IoT MQTT Panel
The Android client will have the following user interface. The labels indicate the panel type (Gauge, LED
indicator or Button), topic subscribed or publish and payload.

4 Panels
Indicates
Gauge
Connection is
Subscribe topic:
good
sxxxxxxxx/room/status/sensor
Payload:
“0” to “4095”

LED Indicator
Button Button
Subscribe topic:
Publish topic: Publish topic:
sxxxxxxxx/room/status/lamp1
sxxxxxxxx/room/cmd/lamps sxxxxxxxx/room/cmd/lamp1
Payload:
Payload: Payload:
“0” (off) or “1” (on)
“Q” (query) “T” (toggle)

The topics and payload is also summarized in the table found in preparation section 7.3B.
5. Run IoT MQTT Panel on Android (or BlueStacks 5). Initial screen asks you to create a connection. If you
already had connection(s) setup, you can also create a new one using the ‘+’ icon.

“iotg home”
1

Leave this blank. It will create


a unique random name
2
“broker.hivemq.com”

3
After click +, enter this name
“home dashboard” 4

IOTG Lab 5 Apr 2023 Page 12 of 23


6. You should have a successful connection shown. You can start to setup a dashboard with panels:
gauge, LED indicator and buttons.

2
Start to add panels
Connection is good to dashboard
1
Touch to setup If you already have panels,
dashboard use this to add new panels
You can duplicate a panel

7. Create a Gauge panel to subscribe topic “sxxxxxxxx/room/status/sensor” to receive sensor reading.

2
“sensor reading”

…/room/status/sensor
3

5
“4095”

1 4 “0” 6
Add a “Gauge”

8. Add a LED indicator to subscribe “sxxxxxxxx/room/status/lamp1” to show lamp1 status, followed by


a Button for “sxxxxxxxx/room/cmd/lamp1” to publish command to toggle lamp1.

1 “lamp1” 7
“lamp1 button”

…/room/status/lamp1 2 …/room/cmd/lamp1
8

3 “1”
9 “T”
4 “0” 5

6 10

IOTG Lab 5 Apr 2023 Page 13 of 23


9. Lastly add another Button to publish command to request lamps statuses. You can select a panel and
use “Panel Width” to change its width, e.g. 1/2 screen to achieve final display below.

1
“get lamps status”

…/room/cmd/lamps 2

3 “Q”
Set selected panel to different width

Final dashboard
with 4 panels

B.3 Testing Android and PC ESP32 clients


We are now ready to test the setup.
10. Android Client publish to PC ESP32 Client
Ensure that the PC ESP32 client (MQTT-Explorer simulating ESP32 client) on the laptop has a good
connection.
At the Android client (IoT MQTT Panel), touch the “GET LAMPS STATUS” and “LAMP1 BUTTON”. You
should observe topics and payload received at the PC ESP32 client (MQTT-Explorer).

(You may need to expand the item to see details as shown.)


If you can’ observe the above, possible problems are:
- Android client connection or 2 buttons topics they publish are incorrect.
- PC ESP32 client connection or the 2 topics subscribed are incorrect.
If the above works, what does it prove concerning the Android client and PC ESP32 client setups?
___________________________________________________________________________________
___________________________________________________________________________________

IOTG Lab 5 Apr 2023 Page 14 of 23


11. PC ESP32 client publish to Android client: At the PC ESP32 client, publish 2 topics with payload shown
and observe the display at the Android client.

1 5

6 7
2 3 4
PC ESP32 Client Publish
Android Client
Sensor reading Display
received & displayed

Lamp1 status of “1”


received and displayed “on”

The above proves that the 2 clients are communicating correctly with correct topics and payloads.
We can now proceed to test the Android client with the actual ESP32. We will first test with the simple
mqttSensor sketch on ESP32 that represents a battery-operated smart sensor.
CHECKPOINT 2: Show your working PC ESP32 client and Android client to supervisor: ______________

C. A Battery-Operated Sensor
The mqttSensor sketch simulates a battery-operated sensor, publishing sensor reading at regular intervals.
12. Open mqttSensor sketch. Replace “s12345678” at “rootT” with your student number.
With the Serial Monitor open, run the sketch. Make sure there’s no error encountered. Observe at
the Serial Monitor and the Android client. State the following:
WiFi AP name: ________________________________________________________________________
IP address given: ______________________________________________________________________
MQTT broker name and port number: _____________________________________________________
ESP32 MQTT client name: ______________________________________________________________
Topic published: ______________________________________________________________________
A sample payload content: _____________________________________________________________
Assuming that there’s no error detected during the program execution, what does this program do?
__________________________________________________________________________________
__________________________________________________________________________________
Time taken to complete the process of connect to WiFi, MQTT broker, publish and disconnect:
__________________________ (no fixed value)
What is the meaning when the Green LED blink once?
___________________________________________________________________________________
IOTG Lab 5 Apr 2023 Page 15 of 23
The program goes to deep sleep for how long before the next reading? _________________________
Note that the program reports the cause of the system boot at the beginning.
After the first boot, the subsequent boots “wake up reason” are cause by: _______________________
Unfortunately, sometimes “Brownout detector triggered” is encountered during wake-up.
Refer to the ESP32 kit. Anything can be done to the hardware to reduce power consumption further?
___________________________________________________________________________________
13. To simulate an error, change the wifi ssid to an invalid one. Which LED would blink? ______________
If you miss observing that, press ESP32 reset button.
Restore the correct ssid and try an invalid broker URL. Which LED would blink? ___________
Restore all after testing.
CHECKPOINT 3: Show your answers to the supervisor________________

D. Home Monitoring and Control


D.1 Remote Home Monitoring & Control
14. Open mqttHome sketch. Replace “s12345678” at “rootT” with your student number. Run the
program. Observe at Serial Monitor, LEDs at ESP32 and the Android client.
15. Observation at Serial Monitor on topic published at 5s intervals. (Adjust rotary to see value change.)
____________________________________________________________________________________
Observation at Android: ________________________________________________________________
16. At ESP32, press PB1 multiple times. Observations … (concise description will do)
At LED1: ____________________________________________________________________________
At Android: __________________________________________________________________________
At Serial Monitor: _____________________________________________________________________
17. At Android, touch “LAMP1 BUTTON” multiple times. Observations … (concise description will do)
At LED1: ____________________________________________________________________________
At Android: _________________________________________________________________________
At Serial Monitor: ____________________________________________________________________
18. Study the codes with understanding from the sketch “mqttHome”.
19. Open a new sketch and save it as “mqtt”. Without the use of #include "mqttHome.h", write codes to
establish WiFi connection as well as connection to broker.hivemq.com
There is no need to use event loop, no need to set ESP32 to sleep, no need to use ticker, no need to
publish any message, no need to subscribe to any topics.
Submit your codes to Politemall

IOTG Lab 5 Apr 2023 Page 16 of 23


20. Save the sketch “mqtt” as “mqttHomeA”. Use #include <delays.h> to read from analog port A5 every
500ms. Publish the analog reading to broker.hivemq.com with the following:
Topic Payload Remarks
s12345678/room/status/sensor Analog reading (0 to 4095) Please replace s12345678 with
your own ID
You may refer to the function
publishSensor( ) in
“mqttHome”

You do not have to subscribe to any topics.


You do not have to write any code for the function mqttCallback( )
Observe your PC ESP32 Client or Android Client to see updates when you rotate the potentiometer.
Submit your codes to Politemall.
21. Save the sketch “mqttHomeA” as mqttHomeB”.
Publish the status to broker.hivemg.com with the following:
Topic Payload Remarks
s12345678/room/status/lamp1 “0” when LED is turn off Please replace s12345678 with
your own ID
“1” when LED is turn on
You may refer to the function
publishLamp1Status( ) in
“mqttHome”
Use a DELAYMS_T object to alternatively publish the payload “0” every 1 second, then followed by “1”
every 1 second.
You do not have to turn on or turn off the Red LED on ESP32.
You do not have to subscribe to any topics.
You do not have to write any code for the function mqttCallback( )
Observe your PC ESP32 Client or Android Client to see updates when the Red LED blinks.
Expect some delays in the updates. Why? __________________________________________
Submit your codes to Politemall.
22. Save the sketch “mqttHomeB” as mqttHomeC”. Subscribe to the topic in serial number 21
(s12345678/room/status/lamp1) as above. Note that s12345678 should be replaced with your own ID.
At the mqttCallback( ) function, use digitalWrite( ) to turn on or to turn off the Red LED.
You may refer to the function mqttCallback( ) in “mqttHome”
Observe your PC ESP32 Client or Android Client to see updates when the Red LED blinks.
Observe that the Red LED on ESP32 also blinks.
Expect some delays in Red LED updates on ESP32 Why? ______________________________________
Submit your codes to Politemall.

IOTG Lab 5 Apr 2023 Page 17 of 23


D.2 Using Wild Card
23. Save “mqttHomeC” as “mqttHomeD”. Repeat serial number 21 and 22 for the Yellow and Green LED.
Use the following topics:
Topic Payload Remarks
s12345678/room/status/yellowLED “0” when LED is turn off Please replace s12345678 with
your own ID
“1” when LED is turn on
Toggle message every 1.5
seconds
You may refer to the function
publishLamp1Status( ) in
“mqttHome”
s12345678/room/status/greenLED “0” when LED is turn off Please replace s12345678 with
your own ID
“1” when LED is turn on
Toggle message every 2
seconds
You may refer to the function
publishLamp1Status( ) in
“mqttHome”

Observed that the Yellow LED on ESP32 is turn on for 1.5 seconds and turn off for 1.5 seconds.
Observed that the Green LED on ESP32 is turn on for 2 seconds and turn off for 2 seconds.
Submit your codes to Politemall.
24. Save “mqttHomeD” as “mqttHomeE”. Remove all topics subscribed.
Observed that without topics subscription all the LEDs do not blink. Why? _______________________
Subscribe to ONLY s12345678/room/status/+ (replace 12345678 with your own ID).
Observed that all the LEDs start blinking again.
Submit your codes to Politemall.
CHECKPOINT 4: Show your answers to the supervisor________________

E. Programming Problem: Add Lamp 2 Monitoring and Control


25. Save mqttHome sketch as lab5-prj-mqttHome.
At ESP32, implement PB2 to control the Lamp2 (Green LED and Grove G2 pin 32), just like PB1 for
Lamp1 at the Red LED and Grove G1 pin 15.
At Android (IoT MQTT Panel), duplicate (do not create from scratch) the previous working “iotg
home” connection and rename as “iotg home2”. Change its dashboard name to “home dashboard2”.
Add in Lamp2 monitoring and control as shown below.

IOTG Lab 5 Apr 2023 Page 18 of 23


At “Connections” use this
to bring out display below

Duplicate the connection


At the dashboard, use
this to duplicate a panel
Remember to change names …

At Android:
Panel Type: _________________ Topic to publish: ___________________________________________
Panel Type: _________________ Topic to subscribe: _________________________________________
At ESP32:
Topic to publish: _______________________________________________
Topic to subscribe: sxxxxxxxx/ ______________________________________
Study the ESP32 program. Some places where you need to add or make changes at ESP32:
- Declare topics to publish and subscribe
- Create EVENT_INPUT_T object for pb2 with its callback that does the necessary
- Create OUTPUT_T for led2 and lamp2 (Grove G2 at pin 32)
- Subscribe to command from Android to toggle lamp2
- Update the callback function to process the command to toggle lamp2
- Publish lamp2 status when there’s any change in lamp2 status
- Update publishAllLampsStatus() to include publishing of lamp2 status
A comment: The topics in the program can streamlined. E.g. instead of two topics
“…/room/cmd/lamp1” and “…/room/cmd/lamps,” it can be just “…/room/cmd” with payloads say “1”
to toggle lamp1, “Q” to request for all lamps’ statuses.
CHECKPOINT 5: Show your working system to the supervisor________________

APPENDIXES

Appendix A: mqttSensor sketch


// mqttSensor.ino

#define rootT "s12345678" // VERY IMPORTANT: change to your student #


// -------------------------------------------------------------------------------------
// IMPORTANT: These 2 MUST BE unique.
// If client is not unique, will get MQTT connection error
// if topic is not unique, you may receive msg from other people
const char *mqttClientName = "mqttClient_" rootT;
const char *topicSensor = rootT "/room/status/sensor"; // Topics to publish
...
#define INTERVAL 20 // interval (sec) to read & report
#define INTERVAL_LONG 60 // interval if error encountered
// -------------------------------------------------------------------------------------
#include <WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
// -------------------------------------------------------------------------------------
IOTG Lab 5 Apr 2023 Page 19 of 23
// These are found in misc.cpp
bool wifiConnect(const char* ssid, const char* password);
void wifiDisconnect();
void bootUpInfo(); // show bootup info at Serial Monitor
void goDeepSleepSec(uint32_t sec); // Go deep sleep for # seconds
void blinkSuccess(); // blink Green LED once for success
void blinkFailure(); // blink Red LED once for failure
// -------------------------------------------------------------------------------------
uint32_t deepSleepDur = INTERVAL; // duration to deep sleep
const char* brokerName = "broker.hivemq.com"; // MQTT server name
int PORTNUM = 1883; // MQTT port number to use
WiFiClient wifiClient; // client for WiFi
PubSubClient mqttClient(wifiClient); // client for MQTT
// -------------------------------------------------------------------------------------
void mqttDisconnect() {
mqttClient.disconnect();
}
// -------------------------------------------------------------------------------------
bool mqttConnect() {
Serial.printf("\n--- Connecting to MQTT Broker: %s."
"\nMQTT client name: %s",
brokerName, mqttClientName);
if (mqttClient.connect(mqttClientName) ) {
Serial.print("\nConnected to broker"); // MQTT connection OK
return true;
}
else {
Serial.print("\nConnection failed. State="); // MQTT connection fail
Serial.print(mqttClient.state() ); // failure info
return false;
}
}
// -------------------------------------------------------------------------------------
void mqttSetupBroker() {
Serial.printf("\nSet broker name to %s at port num %d",
brokerName, PORTNUM);
mqttClient.setServer(brokerName, PORTNUM);
}
// -------------------------------------------------------------------------------------
bool publishSensor() {
uint16_t sensorReading;
char buf[6];
sensorReading = analogRead(A5);
itoa(sensorReading, buf, 10); // integer to string in buf, data to publish
Serial.printf("\nPublishing topic \"%s\""
"\nPayload \"%s\"", topicSensor, buf);
if (mqttClient.publish(topicSensor, buf)) { // publish topic & payload (data)
return true; // publish success
}
return false; // publish failure
}
// -------------------------------------------------------------------------------------
// connect, report and disconnect
void connectReporttDisconnect() {
if (wifiConnect(ssid, password) == false) {
goto error; // error in wifi connection
}
mqttSetupBroker(); // set broker name and port number
if (mqttConnect() == false) { // connect to the broker
wifiDisconnect(); // error in MQTT connection
goto error;
}
if (publishSensor() == false) { // publish topic and data
mqttDisconnect(); // error in MQTT publish

IOTG Lab 5 Apr 2023 Page 20 of 23


wifiDisconnect();
goto error; // MQTT connection OK, publish ...
}
mqttDisconnect();
wifiDisconnect();
deepSleepDur = INTERVAL; // normal interval to wakeup
blinkSuccess(); // All OK, blink Green LED
return;
error: // for all error cases, come here
Serial.printf("\nError encountered");
deepSleepDur = INTERVAL_LONG; // longer interval to wakeup due to error
blinkFailure(); // blink Red LED
}
// -------------------------------------------------------------------------------------
void setup() { ... }
// -------------------------------------------------------------------------------------
void loop() {
connectReporttDisconnect(); // connect, report, disconnect
goDeepSleepSec(deepSleepDur); // go deep sleep for # seconds (INTERVAL or INTERVAL_LONG)
}

Appendix B: mqttHome sketch


// mqttHome.ino
#include "mqttHome.h"
// --------------------------------------------
// IMPORTANT: "rootT" MUST BE unique. Used by mqtt client name & topic
// If client is not unique, will get MQTT connection error
// if topic is not unique, you may receive msg from other people

#define rootT "s12345678" // VERY IMPORTANT: change to your student #


const char *mqttClientName = "mqttClient_" rootT;
const char *topicPubSensor = rootT "/room/status/sensor"; // Topics to publish
const char *topicPubLamp1 = rootT "/room/status/lamp1";
const char *topicSubLamp1 = rootT "/room/cmd/lamp1"; // Topics to subscribe
const char *topicSubLamps = rootT "/room/cmd/lamps";
// -------------------------------------------------------------------------------------
...
// -------------------------------------------------------------------------------------
EVENT_TIMER_TICK_T publishSensorTicker; // Regular timer tick to publish sensor
EVENT_INPUT_T pb1; // for lamp control
OUTPUT_T led1(LED_R, LED_R_ON_VAL); // led1 is "lamp1" Red LED
OUTPUT_T lamp1(15, HIGH); // lamp1 at Grove G1 pin 15, HIGH to on
bool mqttConnOK = false;
// -------------------------------------------------------------------------------------
const char* brokerName = "broker.hivemq.com"; // MQTT server name
int PORTNUM = 1883; // MQTT port number
WiFiClient wifiClient; // client for WiFi
PubSubClient mqttClient(wifiClient); // client for MQTT
// -------------------------------------------------------------------------------------
bool mqttConnect() {
if (mqttClient.connect(mqttClientName) ) {
Serial.print("\nConnected to broker"); // MQTT connection OK
return true;
}
else {
Serial.print("\nConnection failed. State="); // MQTT connection fail
Serial.print(mqttClient.state() ); // failure info
return false;
}
}
// -------------------------------------------------------------------------------------
// Setup broker name, port, callback for subscribed topics
void mqttSetupBrokerNCB() {

IOTG Lab 5 Apr 2023 Page 21 of 23


mqttClient.setServer(brokerName, PORTNUM); // set server name and Port
mqttClient.setCallback(mqttCallback); // call this if subscribed topic arrives
}
// -------------------------------------------------------------------------------------
// Subscribe to topics of interest
void mqttSubscribe() {
mqttClient.subscribe(topicSubLamp1); // subscribe to these topics
mqttClient.subscribe(topicSubLamps);
}
// -------------------------------------------------------------------------------------
// There could be > 1 lamp status
void publishAllLampsStatus() { // publish current lamp1 status
publishLamp1Status(); // got lamp2 also?
}
// -------------------------------------------------------------------------------------
// Handle topic ../room/cmd/lamps
void processCmdLamps(String &payload) { // topic ../room/cmd/lamps received
if (payload == "Q") { // payload “Q” – query lamp satus
publishAllLampsStatus();
}
}
// -------------------------------------------------------------------------------------
// Handle topic ../room/cmd/lamp1
void processCmdLamp1(String &payload) { // topic ../room/cmd/lamp1 received
if (payload == "T") { // payload “T” – toggle lamp1
toggleLamp1();
}
}
// -------------------------------------------------------------------------------------
// When a subscribed topic is received, this is executed
void mqttCallback(String topic, byte* data, unsigned int length) {
String payload;
for (int i = 0; i < length; i++) {
payload += (char)data[i]; // build up String for processing
}
Serial.printf("\nMsg received in topic: \"%s\" + payload \"%s\"",
topic.c_str(), payload.c_str());
// Check which topic received and process the payload
if (topic == topicSubLamp1) { // ../room/cmd/lamp1
processCmdLamp1(payload);
}
else if (topic == topicSubLamps) { // ../room/cmd/lamps
processCmdLamps(payload);
}
}
// -------------------------------------------------------------------------------------
// Publish a topic with its payload
bool publishTopic(const char* topic, const char *str) {
if (mqttClient.publish(topic, str)) {
return true; // OK
}
else {
return false; // error encountered
}
}
// -------------------------------------------------------------------------------------
// Every 5s publish sensor reading
void publishSensor() { ... }
// -------------------------------------------------------------------------------------
// call when Lamp1 change due to PB1 or remote command
void publishLamp1Status() {
if (!mqttConnOK) {
return;
}

IOTG Lab 5 Apr 2023 Page 22 of 23


char buf[2] = "0"; // for 1 character string
buf[0] = lamp1.isOn() ? '1' : '0';
publishTopic(topicPubLamp1, buf);
}
// -------------------------------------------------------------------------------------
// called by PB1 pressed and remote client to toggle
void toggleLamp1() {
Serial.print("\nToggle led1 and lamp1; publish ...");
led1.toggle();
if (led1.isOn()) {
lamp1.on(); // On lamp1 at P15
}
else {
lamp1.off(); // Off lamp1 at P15
}
publishLamp1Status(); // MQTT publish lamp1 status
}
// -------------------------------------------------------------------------------------
void pb1PressCB() { // PB1 pressed handler
toggleLamp1(); // this is also call due to remote client
}
// -------------------------------------------------------------------------------------
// This is called upon WiFi connection success
void wifiConnToDo() { // Called when WiFi connected
mqttSetupBrokerNCB(); // do MQTT setups
if (mqttConnect()) {
mqttSubscribe();
mqttConnOK = true;
publishAllLampsStatus(); // sent to clients current lamp status
}
else {
mqttConnOK = false; // MQTT connection problem!
}
}
// -------------------------------------------------------------------------------------
// This is called when WiFi is disconnected
void wifiDisconnToDo() { // Called when WiFi disconnected
mqttConnOK = false; // set flag indicating things unwell
}
// -------------------------------------------------------------------------------------
void setup() {
...
wifiSetup(wifiConnToDo, wifiDisconnToDo); // 2 WiFi events callback
publishSensorTicker.begin(publishSensor, 5000); // call every 5s
pb1.begin(pb1PressCB, PB1, INPUT_PULLUP, 50, PB1_ON_VAL); // pb1 on/off lamp1
...
}
// -------------------------------------------------------------------------------------
void loop() {
eventloop(); // service event object
mqttClient.loop(); // call regularly to service MQTT matters
}

IOTG Lab 5 Apr 2023 Page 23 of 23

You might also like