Complete MQTT Implementation Example for STM32 (STM32F407 + Ethernet)
Here's a step-by-step guide with code examples to implement MQTT communication on an STM32F407 Discovery board with Ethernet (LAN8720 PHY). We'll use FreeRTOS, LwIP, and Eclipse Paho MQTT.
1. Hardware Setup
Board: STM32F407 Discovery (with RMII Ethernet)
PHY: LAN8720 (built-in)
Network: Router with DHCP
MQTT Broker: test.mosquitto.org (public broker)
2. Software Configuration (STM32CubeMX)
Create Project:
Select STM32F407VG in CubeMX
Enable ETH in Connectivity
Enable RMII interface
Enable LWIP in Middleware
Enable FreeRTOS
Clock Configuration:
Set HCLK to 168MHz
Enable MCO1 to output 50MHz for PHY
Generate Code:
Generate with Toolchain: SW4STM32 (or your preferred IDE)
3. Project Structure
YourProject/ ├── Core/ │ ├── Inc/ │ │ ├── mqtt_client.h │ │ ├── network.h │ ├── Src/ │ │ ├── mqtt_client.c │ │ ├── network.c ├── LWIP/ ├── Middleware/ │ ├── eclipse-paho-mqtt/ (Paho MQTT embedded-C) ├── Drivers/
4. Porting Paho MQTT
Download Paho MQTT Embedded C:
git clone https://github.com/eclipse/paho.mqtt.embedded-cCopy to Project:
Add
MQTTPacket/srcto your project.Exclude
SSLSocket.c(unless using TLS).
Modify
transport.cfor LwIP:int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen) { return netconn_write(sock, buf, buflen, NETCONN_COPY); } int transport_getdata(unsigned char* buf, int count) { return netconn_recv(sock, buf, count, NETCONN_COPY); }
5. Network Initialization
network.c
#include "lwip/netif.h" #include "lwip/dhcp.h" struct netif gnetif; // Global network interface void Network_Init(void) { ip_addr_t ipaddr, netmask, gw; // Initialize LwIP stack MX_LWIP_Init(); // Start DHCP netif_set_up(&gnetif); dhcp_start(&gnetif); // Wait for IP while (netif_is_up(&gnetif) == 0 || ip_addr_isany_val(*netif_ip4_addr(&gnetif))) { osDelay(100); } }
6. MQTT Client Implementation
mqtt_client.c
#include "MQTTClient.h" #include "network.h" #define MQTT_BROKER "test.mosquitto.org" #define MQTT_PORT 1883 #define CLIENT_ID "STM32F407_Client" Network network; MQTTClient client; void messageArrived(MessageData* data) { char msg[50]; memcpy(msg, data->message->payload, data->message->payloadlen); printf("Received: %s\n", msg); } void MQTT_Init(void) { NetworkInit(&network); MQTTClientInit(&client, &network, 3000, sendbuf, sizeof(sendbuf), readbuf, sizeof(readbuf)); MQTTPacket_connectData config = MQTTPacket_connectData_initializer; config.clientID.cstring = CLIENT_ID; config.keepAliveInterval = 60; config.cleansession = 1; int rc = MQTTConnect(&client, &config); if (rc != 0) printf("MQTT Connect failed: %d\n", rc); else printf("Connected to MQTT Broker\n"); MQTTSubscribe(&client, "stm32/sub", QOS1, messageArrived); } void MQTT_Publish(const char* topic, const char* payload) { MQTTMessage message; message.qos = QOS1; message.retained = 0; message.payload = (void*)payload; message.payloadlen = strlen(payload); MQTTPublish(&client, topic, &message); }
7. Main Application
main.c
#include "mqtt_client.h" #include "cmsis_os.h" void StartMQTTTask(void const * argument) { MQTT_Init(); while (1) { MQTT_Publish("stm32/pub", "{\"temp\":25}"); osDelay(5000); // Publish every 5 sec } } int main(void) { HAL_Init(); SystemClock_Config(); MX_LWIP_Init(); osThreadDef(MQTT_Task, StartMQTTTask, osPriorityNormal, 0, 1024); osThreadCreate(osThread(MQTT_Task), NULL); osKernelStart(); }
8. Testing
Connect STM32 to Ethernet.
Monitor Serial Output (UART debug):
Connected to MQTT Broker Published: {"temp":25}Test with MQTT Client (e.g.,
mosquitto_sub):mosquitto_sub -h test.mosquitto.org -t "stm32/pub"
9. Troubleshooting
| Issue | Solution |
|---|---|
| No Ethernet Link | Check PHY (LAN8720) reset, RMII pins |
| DHCP Fails | Assign static IP in network.c |
| MQTT Timeout | Verify broker IP, firewall settings |
| Memory Overflow | Adjust MEM_SIZE in lwipopts.h |
10. Enhancements
MQTT over TLS: Use
mbedTLSfor encryption.JSON Payloads: Integrate
cJSONfor structured data.OTA Updates: Subscribe to firmware topics.

评论
发表评论