I've been learning MQTT recently and found that MQTT is quite useful, so I spent some time making a simple application example, hoping to give some reference to those who need to do this.
Related background knowledge: http://www.embed-net.com/thread-224-1-1.html
The specific functions are:
1. STM32F405 is the main control chip, which collects environmental data through sensors, such as temperature, humidity, light intensity, atmospheric pressure, etc.;
2. The main control chip publishes the measured data to the MQTT server through the W5500 module through the MQTT protocol (the server domain name and IP are shown in the firmware program);
3. The main control subscribes to the message of LED light control, and lights up or turns off the corresponding LED light after receiving the corresponding control command;
4. The Android phone subscribes to the message of sensor data, and displays the sensor data on the interface after receiving the message;
5. The Android phone can send the command to light up or turn off the LED light to the server, and then the server will forward the command to the STM32 main control, and then the STM32 main control will parse the command and execute the command.
1 Implementation of MQTT protocol on MCU side
is based on TCP protocol, so we only need to implement TCP client code on MCU side and then it will be easy to transplant MQTT. We have implemented TCP client code for STM32F4+W5500 before, and the code download address is:
http://www.embed-net.com/thread-87-1-1.html
Of course, if you want to connect directly using server domain name in the code, we also have to integrate DNS code in TCP client code, and of course there is related code in the above link.
MQTT code source download address:
http://www.eclipse.org/paho/
On the STM32 side, we use C/C++ MQTT Embedded clients code.
The hardware connection is shown in the figure below:
1.1 MQTT transplantation
MQTT transplantation is very simple, add C/C++ MQTT Embedded clients code to the project, and then we only need to encapsulate 4 functions again:
int transport_sendPacketBuffer(unsigned char* buf, int buflen);
int transport_getdata(unsigned char* buf, int count);
int transport_open(void);
int transport_close(void);
transport_sendPacketBuffer: Send data through the network in TCP mode;
transport_getdata: Read data from the server in TCP mode, this function is currently a blocking function;
transport_open: Open a network interface, which is actually to establish a TCP connection with the server;
transport_close: Close the network interface.
If the socket-based TCP client program has been transplanted, then the encapsulation of these functions is also very simple, and the program code is as follows:
int transport_sendPacketBuffer(unsigned char* buf, int buflen)
{
return send(SOCK_TCPS,buf,buflen);
}
int transport_getdata(unsigned char* buf, int count)
{
return recv(SOCK_TCPS,buf,count);
}
int transport_open(void)
{
int32_t ret;
//Create a new socket and bind to local port 5000
ret = socket(SOCK_TCPS,Sn_MR_TCP,5000,0×00);
if(ret != SOCK_TCPS){
printf(“%d:Socket Error”,SOCK_TCPS);
while(1);
}else{
printf(“%d:Opened”,SOCK_TCPS);
}
//Connect to TCP server
ret = connect(SOCK_TCPS,domain_ip,1883); //Port must be 1883
if(ret != SOCK_OK){
printf(“%d:Socket Connect Error”,SOCK_TCPS);
while(1);
}else{
printf(“%d:Connected”,SOCK_TCPS);
}
return 0;
}
int transport_close(void)
{
close(SOCK_TCPS);
return 0;
}
After completing these functions, we can implement our own code according to the official sample code. For example, the code for sending a message to the proxy server is as follows:
int mqtt_publish(char *pTopic,char *pMessage)
{
int32_t len,rc;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
unsigned char buf[200];
MQTTString topicString = MQTTString_initializer;
int msglen = strlen(pMessage);
int buflen = sizeof(buf);
data.clientID.cstring = “me”;
data.keepAliveInterval = 5;
data.cleansession = 1;
len = MQTTSerialize_connect(buf, buflen, &data);
topicString.cstring = pTopic;
len += MQTTSerialize_publish(buf + len, buflen – len, 0, 0, 0, 0, topicString, (unsigned char*)pMessage, msglen);
len += MQTTSerialize_disconnect(buf + len, buflen – len);
transport_open();
rc = transport_sendPacketBuffer(buf,len);
transport_close();
if (rc == len)
printf(“Successfully published
”);
else
printf(“Publish failed
”);
return 0;
}[page]
Let's take a look at the code of the main function, the idea is also clear:
int main(void)
{
static char meassage[200];
int rc;
char *led;
char led_value;
float temperature,humidity,light,pressure;
srand(0);
//配置LED灯引脚
LED_Config();
//初始化配置网络
network_init();
while(1){
memset(meassage,0,sizeof(meassage));
//订阅消息
rc = mqtt_subscrib(“pyboard_led”,meassage);
printf(“rc = %d
”,rc);
if(rc >= 0){
printf(“meassage = %s
”,meassage);
//解析JSON格式字符串并点亮相应的LED灯
cJSON *root = cJSON_Parse(meassage);
if(root != NULL){
led = cJSON_GetObjectItem(root,”led”)->valuestring;
printf(“led = %s
”,led);
led_value = cJSON_GetObjectItem(root,”value”)->valueint;
if(!strcmp(led,”red”)){
if(led_value){
LED_On(LED_RED);
}else{
LED_Off(LED_RED);
}
}else if(!strcmp(led,”green”)){
if(led_value){
LED_On(LED_GREEN);
}else{
LED_Off(LED_GREEN);
}
}else if(!strcmp(led,”blue”)){
if(led_value){
LED_On(LED_BLUE);
}else{
LED_Off(LED_BLUE);
}
}else if(!strcmp(led,”yellow”)){
if(led_value){
LED_On(LED_YELLOW);
printf(“Yellow On
”);
}else{
LED_Off(LED_YELLOW);
printf(“Yellow Off
”);
}
}
// 释放内存空间
cJSON_Delete(root);
}else{
printf(“Error before: [%s]
”,cJSON_GetErrorPtr());
}
}
delay_ms(500);
//获取传感器测量数据,该示例使用随机数
temperature = rand()P;
humidity = rand()0;
light = rand()00;
pressure = rand()00;
//将数据合成为JSON格式数据
sprintf(meassage,”{”temperature”:%.1f,”humidity”:%.1f,”light”:%.1f,”pressure”:%.1f}”,temperature,humidity,light,pressure);
//将数据发送出去
mqtt_publish(“pyboard_value”,meassage);
}
}
The complete project code can be downloaded in the attachment below.
2 Mobile phone code implementation
We also use the official Java library Java client and utilities for the mobile phone. Download address:
http://www.eclipse.org/paho/
. Just add the jar file to the project. The program interface is as follows:
The above 4 items respectively show the sensor measurement data sent by the STM32 microcontroller to the server through W5500;
the following 4 pictures respectively control the 4 LED lights on the board;
we use threads to send messages and callback functions to receive messages.
2.1 Implement message sending
The code for sending a message is as follows:
class PublishThread extends Thread {
String topic;
MqttMessage message;
int qos = 0;
MemoryPersistence persistence = new MemoryPersistence();
PublishThread(String topic,String message){
this.topic = topic;
this.message = new MqttMessage(message.getBytes());
}
public void sendMessage(String topic,String message){
this.topic = topic;
this.message = new MqttMessage(message.getBytes());
run();
}
@Override
public void run() {
try {
MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setKeepAliveInterval(1);
System.out.println(“Connecting to broker: ” + broker);
sampleClient.connect(connOpts);
System.out.println(“Connected”);
System.out.println(“Publishing message: ” + message.toString());
message.setQos(qos);
sampleClient.publish(topic, message);
System.out.println(“Message published”);
sampleClient.disconnect();
System.out.println(“Disconnected”);
}catch(MqttException me) {
System.out.println(“reason “+me.getReasonCode());
System.out.println(“msg “+me.getMessage());
System.out.println(“loc “+me.getLocalizedMessage());
System.out.println(“cause “+me.getCause());
System.out.println(“excep “+me);
me.printStackTrace();
}
}
}
2.2 Implement message reception
The code for receiving messages is as follows:
class SubscribeThread extends Thread{
final String topic;
MemoryPersistence persistence = new MemoryPersistence();
SubscribeThread(String topic){
this.topic = topic;
}
@Override
public void run(){
try {
final MqttClient sampleClient = new MqttClient(broker, clientId, persistence);
final MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
System.out.println(“Connecting to broker: ” + broker);
connOpts.setKeepAliveInterval(5);
sampleClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
System.out.println(“connectionLost”);
try {
sampleClient.connect(connOpts);
sampleClient.subscribe(topic);
}catch (MqttException e){
e.printStackTrace();
}
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
System.out.println(“messageArrived:”+mqttMessage.toString());
System.out.println(topic);
System.out.println(mqttMessage.toString());
try {
JSONTokener jsonParser = new JSONTokener(mqttMessage.toString());
JSONObject person = (JSONObject) jsonParser.nextValue();
temperature = person.getDouble(“temperature”);
humidity = person.getDouble(“humidity”);
light = person.getDouble(“light”);
pressure = person.getDouble(“pressure”);
System.out.println(“temperature = ” + temperature);
System.out.println(“humidity = ” + humidity);
runOnUiThread(new Runnable() {
@Override
public void run() {
temperatureTextView.setText(String.format(“%.1f”, temperature));
humidityTextView.setText(String.format(“%.1f”, humidity));
lightTextView.setText(String.format(“%.1f”, light));
pressureTextView.setText(String.format(“%.1f”, pressure));
}
});
} catch (JSONException ex) {
ex.printStackTrace();
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
System.out.println(“deliveryComplete”);
}
});
sampleClient.connect(connOpts);
sampleClient.subscribe(topic);
} catch(MqttException me) {
System.out.println(“reason “+me.getReasonCode());
System.out.println(“msg “+me.getMessage());
System.out.println(“loc “+me.getLocalizedMessage());
System.out.println(“cause “+me.getCause());
System.out.println(“excep “+me);
me.printStackTrace();
}
}
}
3 Actual test results
1. The MCU updates the sensor data regularly, and the mobile phone will also update synchronously;
2. When the mobile phone clicks the buttons controlled by the 4 LEDs, the corresponding LEDs on the board will light up or go out;
4 Source code download
4.1 STM32 source code download
4.2 Mobile source code download
4.3 Mobile apk download
Previous article:About ARM assembly instruction DCD
Next article:ARM mbed platform WIZwiki-W7500 user manual
Recommended ReadingLatest update time:2024-11-16 16:32
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- In fact, Valentine's Day 20200214 was cancelled
- This problem occurs when setting up the stm8 environment. What is the reason? Thank you
- dsp28335 data space
- [Xianji HPM6750 Review 8] Detailed description of the small twists and turns encountered by SPI peripherals
- MSP430 MCU Development Record (16)
- I posted a thread about icebabycool. He didn't answer the question but laughed at me instead of showing my low IQ. Please punish this kind of rogue behavior severely.
- Help with POE design issues
- [Voice and vision module based on ESP32S3] Material unpacking—ESP32S3 BOX
- PCBA intelligent detection fixture, one-click generation of test reports
- How to choose the right inductor in a switching power supply