MQTT Protocol
Part 3: MQTT
History of MQTT
MQTT and the ISO model
MQTT Architecture
3.1 What is MQTT?
MQTT stands for Message Queuing Telemetry Transport. MQTT is a machine to machine
internet of things connectivity protocol. It is an extremely lightweight and publish-subscribe
messaging transport protocol. This protocol is useful for the connection with the remote location
where the bandwidth is a premium. These characteristics make it useful in various situations,
including constant environment such as for communication machine to machine and internet of
things contexts. It is a publish and subscribe system where we can publish and receive the
messages as a client. It makes it easy for communication between multiple devices. It is a simple
messaging protocol designed for the constrained devices and with low bandwidth, so it's a perfect
solution for the internet of things applications
Characteristics of MQTT The MQTT has some unique features
which are hardly found in other protocols. Some of the features of an
MQTT are given below:
- It is a machine to machine protocol, i.e., it provides communication between the devices.
- It is designed as a simple and lightweight messaging protocol that uses a publish/subscribe
system to exchange the information between the client and the server.
- It does not require that both the client and the server establish a connection at the same time.
- It provides faster data transmission, like how Whats App/messenger provides a faster delivery.
It's a real-time messaging protocol.
- It allows the clients to subscribe to the narrow selection of topics so that they can receive the
information they are looking for
3.2 History of MQTT
The MQTT was developed by Dr. Andy Stanford-Clark (IBM), and Arlen Nipper (Erotech). The
previous versions of protocol 3.1 and 3.1.1 were made available under MQTT ORG. In 2014, the
MQTT was officially published by OASIS. The OASIS becomes a new home for the
development of the MQTT. Then, the OASIS started the further development of the MQTT.
Version 3.1.1 is backward comfortable with a 3.1 and brought only minor changes such as
changes to the connect message and clarification of the 3.1 version. The recent version of MQTT
is 5.0, which is a successor of the 3.1.1 version. Version 5.0 is not backward, comfortable like
version 3.1.1. According to the specifications, version 5.0 has a significant number of features
that make the code in place.
The major functional objectives in version 5.0 are:
- Enhancement in the scalability and the large-scale system in order to set up with the thousands
or the millions of devices.
- Improvement in the error reporting
3.3 Where are MQTT?
Internet Protocol Suite We are here!
HTTP, Application layer
Websockets,
DNS,
XMPP,
MQTT,
CoAp
TLS, SSL Application Layer
(Encryption)
TCP, UDP Transport
IP(V4, V6), Internet Layer
6LowPAN
Ethernet, Link Layer
802.11
WiFi,
802.15.4
3.3 Where are MQTT?
Example: Google and MQTT
https://www.google.com/url?sa=i&url=https%3A%2F%2Fmedium.com%2Fgoogle-cloud%2Fbuild-a-weather-station-
using-google-cloud-iot-core-and-mongooseos-7a78b69822c5&psig=AOvVaw1cCYrnzi7w8xvAlP-
X6FSK&ust=1715242086523000&source=images&cd=vfe&opi=89978449&ved=0CBIQjRxqFwoTCNiKkoHN_YUDFQ
AAAAAdAAAAABAI
3.3 Where are MQTT?
Google IoT-Core
3.3 Where are MQTT?
Why Choose HiveMQ to integrate MQTT data with Google Cloud?
https://www.google.com/search?sca_esv=8062de9ce58a314a&sca_upv=
1&q=google+cloud+platform+mqtt&tbm=isch&source=lnms&sa=X&ve
d=2ahUKEwjm4-
y3zP2FAxUI7zgGHVbjDJ0Q0pQJegQICRAB&biw=1920&bih=911&d
pr=1#imgrc=DD9E1WgUWVh4pM
3.3 Where are MQTT?
Why Choose HiveMQ to integrate MQTT data with Google Cloud?
https://www.hivemq.com/solutions/the-leading-mqtt-broker-primed-
for-google-cloud/
3.3 Where are MQTT?
Why Choose HiveMQ to integrate MQTT data with Google Cloud?
https://www.iqhome.org/solutions/iot-mqtt
3.3 Where are MQTT?
https://www.motioncontroltips.com/part-5-motion-control-mqtt-opc-
ua-and-other-protocols-for-cloud-services/
3.3 Where are MQTT?
available from: The International Journal of Advanced Manufacturing Technology
3.4 MQTT Architecture
MQTT Architecture
MQTT Architecture To understand the
MQTT architecture, we first look at the
components of the MQTT.
- Message
- Client
- Server or Broker
- TOPIC
Message
The message is the data that is carried
out by the protocol across the network
for the application. When the message
is transmitted over the network, then the
message contains the following
parameters:
1. Payload data https://www.researchgate.net/figure/MQTT-Architecture-2-Broker-
2. Quality of Service (QoS) Broker-controls-the-distribution-of-information-and-
3. Collection of Properties mainly_fig1_316018571
4. Topic Name
3.4 MQTT Architecture
Client
In MQTT, the subscriber and publisher are the two roles of a client. The clients subscribe to the
topics to publish and receive messages. In simple words, we can say that if any program or device
uses an MQTT, then that device is referred to as a client. A device is a client if it opens the
network connection to the server, publishes messages that other clients want to see, subscribes to
the messages that it is interested in receiving, unsubscribes to the messages that it is not interested
in receiving, and closes the network connection to the server.
In MQTT, the client performs two operations:
Publish: When the client sends the data to the server, then we call this operation as a publish.
Subscribe: When the client receives the data from the server, then we call this operation a
subscription.
3.4 MQTT Architecture
Server or broker
The device or a program that allows the client to publish the messages and subscribe to the
messages. A server accepts the network connection from the client, accepts the messages from the
client, processes the subscribe and unsubscribe requests, forwards the application messages to the
client, and closes the network connection from the client
TOPIC
The label provided to the message is checked against the subscription known by the server is
known as TOPIC
3.4 MQTT Architecture
Example of Architecture of MQTT
Now we will look at the architecture of MQTT. To understand it more clearly, we will look at the
example:
Suppose a device has a temperature sensor and wants to send the rating to the server or the
broker. If the phone or desktop application wishes to receive this temperature value on the other
side, then there will be two things that happened. The publisher first defines the topic; for
example, the temperature then publishes the message, i.e., the temperature's value. After
publishing the message, the phone or the desktop application on the other side will subscribe to
the topic, i.e., temperature and then receive the published message, i.e., the value of the
temperature. The server or the broker's role is to deliver the published message to the phone or
the desktop application
3.6 MQTT protocol
MQTT Message Format
The MQTT uses the command and the command acknowledgment format, which means that
each command has an associated acknowledgment. As shown in the above figure that the connect
command has connect acknowledgment, subscribe command has subscribe acknowledgment, and
publish command has publish acknowledgment. This mechanism is similar to the handshaking
mechanism as in TCP protocol
3.6 MQTT protocol
The packet structure or message format of the MQTT
The MQTT message format consists of 2 bytes fixed header, which is present in all the MQTT
packets. The second field is a variable header, which is not always present. The third field is a
payload, which is also not always present. The payload field basically contains the data which is
being sent. We might think that the payload is a compulsory field, but it does not happen. Some
commands do not use the payload field, for example, disconnect message
3.6 MQTT protocol
Fixed Header
Let's observe the format of the fixed header:
As we can observe in the above format that the fixed header contains two bytes. The first byte
contains the following fields:
-MQTT Control Packet Type: It occupies 4 bits, i.e., 7 to 4-bit positions. This 4- bit is an assigned
value, and each bit represents the MQTT control packet type.
- Flag specific to each MQTT packet type: The remaining 4-bits represent flag specific to each
MQTT packet type
The byte 2 contains the remaining length, which is a variable-length byte integer. It represents the
number of bytes remaining in a current control packet, including data in the variable header and
payload. Therefore, we can say that the remaining length is equal to the sum of the data in the
variable header and the payload
3.6 MQTT protocol
MQTT Control Packet Types
The above table shows the control packet types with 4-bit value and direction flow. As we can
observe that every command is followed by acknowledgment like CONNECT has CONNACK,
PUBLISH has PUBACK, PUBREC, PUBREL, and PUBCOMP, SUBSCRIBE has SUBACK,
UNSUBSCRIBE has UNSUBACK
3.7 ESP8266
•802.11 b/g/n
•Wi-Fi Direct (P2P), soft-AP
•Integrated TCP/IP protocol stack
•Integrated TR switch, balun, LNA, power amplifier and
matching network
•Integrated PLLs, regulators, DCXO and power management
units
•+19.5dBm output power in 802.11b mode
•Power down leakage current of <10uA
•Integrated low power 32-bit CPU could be used as application
processor
•SDIO 1.1 / 2.0, SPI, UART
•STBC, 1×1 MIMO, 2×1 MIMO
•A-MPDU & A-MSDU aggregation & 0.4ms guard interval
•Wake up and transmit packets in < 2ms
•Standby power consumption of < 1.0mW (DTIM3)
3.7 ESP8266
Cloud
Router
Internet Wifi:
Pass:
Terminal
software
STM32 board ESP8266
115200;8;N;1
UART2 UART1 UART2
3.7 ESP8266_Application
ESP8266 sử dụng giao tiếp nối tiếp để tương tác với vi điều khiển. Trong bài tập
này TX2 & RX2 của ESP8266 được nối với cổng serial2 (PA2 & PA3) của board
STM32.
Tập lệnh AT dùng để giao tiếp giữa ESP8266 với STM32
AT: Kiểm tra lệnh, luôn trả về "OK"
ATE: cho phép echo
ATE0: không cho phép echo
AT AT+RST: Khởi động lại module
AT + GMR:Hiển thị chi tiết phần mềm
AT + CWMODE = 1 hoặc 2 hoặc 3: Chế độ Wi-Fi 1-Station, 2- AP, 3-Cả hai
AT + CWLAP: Liệt kê AP (wifi)
AT + CWJAP = SSID, PASSWORD: Tham gia AP (wifi)
AT+ CWQAP: Thoát khỏi AP (wifi)
AT + CIFSR: Nhận địa chỉ IP
AT + CIPMUX = 0 hoặc 1: Đặt nhiều kết nối 0 - Đơn, 1 nhiều
3.7 ESP8266_Application
AT + CIPSTART = <loại>, <địa chỉ>, <cổng>:
<loại: kết nối TCP/UDP>, <địa chỉ: địa chỉ IP>, <cổng: địa chỉ cổng của IP kết
nối đơn: Loại-TCP; UDP nhiều kết nối: Id-0 đến 4>
AT + CIPSENDAT + CIPSEND = <chiều dài>: Gửi dữ liệu kết nối đơn, Độ dài
– Độ dài của dữ liệu, nhiều kết nối, Id = 0 đến 4
AT + CIPSTATUS: Có trạng thái kết nối
AT + CIPSERVER = <chế độ>, <cổng>: Đặt làm máy chủ 0 – Đóng máy chủ,
cổng 1 mở
AT + CIPCLOSE: Đóng kết nối TC hoặc UDP
Để giao tiếp được với ESP8266 bằng tập lệnh AT, chúng ta cần phải cập nhật
(download) Firmware cho ESP8266. Để thực hiện công viện này, chúng ta dùng phần
mềm “flash_download_tool_v3.8.5”
3.6 MQTT protocol
Cập nhật (download) Firmware cho ESP8266
B1: chọn “flash_download_tool_v3.8.5.exe”. Sau khi giao diện hiện ra, ta chọn chế độ
“Developer Mode”, tiếp đến chọn “ESP8266 DownloadTool”
B2: Chọn các chế độ:
- SPI Speed: 40MHz
- SPI Mode: DIO
- Flash Size: 8Mbit
- Tốc độ Baud: 115200
- Port giao tiếp: Port nối với ESP8266
3.6 MQTT protocol
B3: Tại file “ESP8266-IDF-AT_V2.1” vào file “download.config”. Ta thấy, các file được kiến
nghị thiết lập cho ESP8266
3.6 MQTT protocol
Kết quả B3
Sau khi hoàn tất, ta nhấn Download là kết thúc quá trình cập nhật (download) Firmware cho
ESP8266
3.7 ESP8266_Application
Viết chương trình cho STM32 giao tiếp ESP8266
B1: Viết chương trình sử dụng hàm Print để xuất dữ liệu debug
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart2,(uint8_t *)&ch,1,0xFFFF);
return ch;
}
B2: Add thư viện cJSON vào project
JSON (JavaScript Object Notation) là một định
dạng chuyển đổi dữ liệu nhanh. Chúng dễ dàng cho
chúng ta đọc và viết; dễ dàng cho thiết bị phân tích.
JSON là một định dạng kiểu text mà hoàn toàn độc
lập với các ngôn ngữ hoàn chỉnh, thuộc họ hàng
với các ngôn ngữ họ hàng C, bao gồm: C, C++, C#,
Java, JavaScript, Perl, Python, và nhiều ngôn ngữ
khác. Những đặc tính đó đã tạo nên JSON một
ngôn ngữ chuyển kiểu dữ liệu thường được dùng
3.7 ESP8266_Application
JSON được xây dựng theo 2 dạng cấu trúc sau:
Dạng 1: Là tập hợp của các cặp tên và giá trị name-value. Trong hầu hết các ngôn ngữ, dạng
cấu trúc này được thấy khi làm việc trên đối tượng (object), ghi (record), cấu trúc (struct),
(dictionary), (hash table), danh sách khoá (keyed list), hay mảng liên hợp.
Dạng 2: Là một tập hợp các giá trị đã được sắp xếp. Trong hầu hết các ngôn ngữ, dạng
cấu trúc này được thấy khi làm việc trên mảng, véc tơ, tập hợp hay là một dãy sequence
3.7 ESP8266_Application
3.7 ESP8266_Application
3.7 ESP8266_Application
B3: Khai báo thư viện cJSON #include <cJSON.h>
B4: Khởi tạo kết nối ESP 8266: HAL_UART_Receive_IT(&huart1, rx_buffer_UART1, 1);
B5: test ket noi Uart thong qua ham printf: printf("Setup Uart2\r\n");
B5: Thiết lập kết nối với ESP 8266 printf("Setting ESP\r\n");
void SettingESP(void) SettingESP();
{
// reset ESP
Send_AT_Commands_Setting("AT+RST\r\n", "OK", 10000 , 0);
HAL_Delay(3000);
// esp co dang hoat dong khong
Send_AT_Commands_Setting("AT\r\n", "OK", 300, 0);
HAL_Delay(3000);
// tat phan hoi khong can
Send_AT_Commands_Setting("ATE0\r\n", "OK" , 2000, 0);
HAL_Delay(3000);
// cai dat che do hoat dong wife: 1,1
Send_AT_Commands_Setting("AT+CWMODE=1,1\r\n", "OK", 2000, 0);
HAL_Delay(3000);
// wifi can ket noi
Send_AT_Commands_Setting("AT+CWJAP=\"TP-Link_9B0E\",\"39072177\"\r\n", "WIFI CONNECTED", 10000, 0);
// \"user name\",\"pass" ( \" TP-Link_9B0E \",\" 39072177 \")
HAL_Delay(3000);
// wifi can ket noi
Send_AT_Commands_Setting("AT+CIPMUX=0\r\n", "OK", 2000 , 0);
HAL_Delay(3000);
ErrorCode = 0;
}
3.7 ESP8266_Application
B4_1: Reset ESP 8266 Send_AT_Commands_Setting("AT+RST\r\n", "OK", 10000 , 0);
void Send_AT_Commands_Setting(char *AT_Commands, char *DataResponse, uint32_t timesend , uint32_t setting)
ESP8266 {
STM32 last = HAL_GetTick();
ConfigAT = setting;
Gửi lệnh char DataSendAT[50];
for(int i = 0 ; i < 50; i++)
{
DataSendAT[i] = 0;// gan ky tu null vao mang DataSendAT
}// dua data lenh AT_Commands vao mang DataSendAT
// xem lenh snprintf trong c. Cú pháp: snprintf(string, size, “format string” , vars). string là chuoi dích, size gioi han du
//lieu dua vao chuoi, “format string” dinh dang chuoi, vars so can chuyen doi);
Gửi trả lời // trong chuong trinh nay ham snprintf se lay chuoi do con tro AT_commands tro toi va cho vao chuoi DataSendAT
snprintf(DataSendAT, sizeof(DataSendAT),"%s\r\n", AT_Commands); // %s xuat ra mot chuoi ky tu
HAL_UART_Transmit(&huart1,(uint8_t *)&DataSendAT,strlen(DataSendAT),1000); // gui du lieu den ESP
printf("Send AT-Commands Setting: %s\r\n", DataSendAT);
// dung doi phan hoi + doi lau qua thi goi tiep ( phan hoi tu ham ngat uart2)
last = HAL_GetTick();
While(1)
{ // qua 5s thi gui lai lenh cu ( gui khi nao ok thi thoi)
Nếu ESP 8266 if(HAL_GetTick() - last >= timesend)
không trả lời {
thì chờ ở đây. HAL_UART_Transmit(&huart1,(uint8_t *)&DataSendAT,strlen(DataSendAT),1000);
printf("Send AT-Commands Setting TimeSend: %s\r\n", DataSendAT);
Chương trình last = HAL_GetTick();
này chưa được }
if(strstr(rx_buffer1,DataResponse) != NULL)// tim trong chuoi nhan duoc co “OK”?
clear, cần cải {
thiện printf("Reponse Setting: %s\r\n",DataResponse);// Debug
clearbuffer_UART_ESP();
break;
}
}
}