STM32+W5500+MQTT+Android realizes remote data acquisition and control

Publisher:WhisperingGlowLatest update time:2015-09-30 Source: eefocusKeywords:STM32  W5500  MQTT  Android Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
0 Introduction

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
 MQTT_STM32_W5500.rar
4.2 Mobile source code download
 MQTT_Android.rar
4.3 Mobile apk download
 stm32_w5500_mqtt_app.rar

Keywords:STM32  W5500  MQTT  Android Reference address:STM32+W5500+MQTT+Android realizes remote data acquisition and control

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

The simplest timing configuration of stm32 basic timer
I have recently used the timing function of the timer. I learned that the timer function of stm32 is very powerful and has a lot of things. The datasheet also talks about it in a long paragraph. I will not go into details about it. Here I will only explain how to configure the simplest timing function configuration.
[Microcontroller]
The simplest timing configuration of stm32 basic timer
Android Q has a problem of constant restarts, Google responded: it will be fixed as soon as possible
      Many users have encountered similar situations where their devices keep restarting after upgrading to the third beta version of Android Q. In particular, the device will restart without any warning, which catches people off guard.        According to the developer, the above situation is caused by Project Main
[Mobile phone portable]
Android Q has a problem of constant restarts, Google responded: it will be fixed as soon as possible
STM32CubeMX----Miscellaneous Notes
(1) When using FSMC as the LCD interface and enabling FreeRTOS at the same time, it is found that the generated project files will have problems after compilation.                   After research, I found that the problem lies in the code "FreeRTOSConfig.h": /* Cortex-M specific definitions. */ #ifdef __NVIC_PR
[Microcontroller]
34. Memory Management
1. Introduction to Memory Management 1. Why use memory management?  For example, how to browse SD card files on LCD If there is memory available for memory management, apply for memory and release it for other use after use. There is no need to define a large array in advance to occupy a lot of memory. 2. What is
[Microcontroller]
34. Memory Management
Android training class (86) bootloader before kernel runs
In fact, it takes a lot of hard work to load and run the kernel of the Android system, because everything is difficult at the beginning. At the beginning of a system, there are no resources to use. The CPU only recognizes the address 0x00000000 and runs the first instruction from there. And this code has a size limi
[Microcontroller]
Stm32 peripheral module programming initialization steps
1. External interruption 1) Initialize the IO port as input. In this step, set the state of the IO port you want to use as the external interrupt input. It can be set to pull-up/pull-down input or floating input, but when floating, it must be pulled up or pulled down externally. Otherwise, the interrupt may be trigge
[Microcontroller]
How does STM32 get the actual VDDA value through internal VREF
We often use the STM32 ADC function to test external voltages. In some situations where the accuracy is not high, we generally use 3.3V as the reference voltage to calculate the measured voltage value. However, this situation is rare, and it may only be used in the microcontroller learning board. Because the 3.3V volt
[Microcontroller]
How does STM32 get the actual VDDA value through internal VREF
Feasibility Analysis of Android Tablet as Car Central Control
In addition to being an Internet terminal, tablets are also multimedia players, navigation devices, and game consoles. Most tablets also have built-in GPS receivers, wireless networks, accelerometers, gyroscopes, etc., which are very helpful for tablets to replace traditional car center consoles, because these function
[Mobile phone portable]
Feasibility Analysis of Android Tablet as Car Central Control
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号