Skip to content

Digital Me

Electronics, Computers at leisure time

Menu
  • Home
  • Contact
  • About
Menu

ESP8266 MQTT client on RTOS

Posted on August 30, 2015

In the recent Maker Faire I demonstrated an ESP8266 MQTT VFD clock. Some readers had wrote to ask for the soure code. Because the project was builtup within only 2 days, the actual source code is more or less of spaghette type. However the underlying MQTT client may be useful to someone who likes the RTOS SDK.

If you search MQTT and ESP8266 on the intraweb, most likely all hits can be traced back to the great work done by TuanPM. However Tuan’s code is based on Espressif’s NON-OS SDK. There has been some great debates about embedded programming with-or-without an OS. To me programming with OS vs NON-OS is like programming with C vs Assembly. I like programming in C, so I wrote a new MQTT client for Espressif’s RTOS SDK.

The source code is published at https://github.com/baoshi/ESP-RTOS-Paho

Here are some notes:

  • The code is based on the Eclipse Paho project, specifically the embedded C client.
  • Socket-level APIs used, the code is thread-safe.
  • Many error handlings were added to the original Paho client, including time-out for most of the network functions. These are designed to work with an RTOS to support automatic error correction at various abused conditions.
  • I’m compiling using the “Unofficial ESP8266 DevKit“. Other toolchain such as esp-open-sdk can be used as well (adjust pathes in Makefile).
  • Skeleton code for connecting a MQTT broker is as follows:

[code]
struct Network network;
MQTTClient client = DefaultClient;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
unsigned char mqtt_buf[100];
unsigned char mqtt_readbuf[100];

NewNetwork(&network);
ConnectNetwork(&network, MQTT_HOST, MQTT_PORT);
NewMQTTClient(&client, &network, 5000, mqtt_buf, 100, mqtt_readbuf, 100);
data.willFlag = 0;
data.MQTTVersion = 3;
data.clientID.cstring = mqtt_client_id; // you client’s unique identifier
data.username.cstring = MQTT_USER;
data.password.cstring = MQTT_PASS;
data.keepAliveInterval = 10; // interval for PING message to be sent (seconds)
data.cleansession = 0;
MQTTConnect(&client, &data);
[/code]

To subscribe to a MQTT topic, use

[code]
MQTTSubscribe(&client, "/mytopic", QOS1, topic_received);
[/code]

The parameter topic_received is a callback function handling the received message:

[code]
// Callback when receiving subscribed message
LOCAL void ICACHE_FLASH_ATTR topic_received(MessageData* md)
{
int i;
MQTTMessage* message = md->message;
dmsg_puts("Received Topic ");
for (i = 0; i t; md->topic->lenstring.len; ++i)
dmsg_putchar(md->topic->lenstring.data[i]);
dmsg_puts(", Message ");
for (i = 0; i < (int)message->payloadlen; ++i)
dmsg_putchar(((char*)message->payload)[i]);
dmsg_puts("rn");
}
[/code]

To publish a MQTT topic, use

[code]
char msg[PUB_MSG_LEN];
MQTTMessage message;
message.payload = msg;
message.payloadlen = PUB_MSG_LEN;
message.dup = 0;
message.qos = QOS1;
message.retained = 0;
MQTTPublish(&client, "topic", &message);
[/code]

The demo project included in the library shows how the MQTT related functions can be organized inside a FreeRTOS task and interact with other tasks, such as retry connection after server error, WiFi error, etc. The following diagram may be helpful to understand the code. (Imaging how this can be done using NON-OS SDK)

MQTT and WiFi Thread
MQTT and WiFi Thread

As Espressif had just teased us with the new ESP32 chip and RTOS is rumored to be the default SDK, I hope this piece of code will be useful.

 

9 thoughts on “ESP8266 MQTT client on RTOS”

  1. John says:
    November 16, 2015 at 8:00 am

    Excellent work! I have the Tuan implementation in my current project but I will look closely at your implementation for the future. Looking forward to the ESP32 as well!

    Reply
  2. Ravi says:
    January 17, 2016 at 12:54 am

    Hello Baoshi,

    I tried compiling your code and I get the below error message:
    I too am using the RTOS SDK 1.3.0. Can you please help me with this?

    c:/espressif/xtensa-lx106-elf/bin/../lib/gcc/xtensa-lx106-elf/5.1.0/../../../../xtensa-lx106-elf/bin/ld.exe: build/app.out section `.irom0.text’ will not fit in region `irom0_0_seg’
    collect2.exe: error: ld returned 1 exit status
    C:/Users/Ravi/workspace/PahoMQTT/Makefile:225: recipe for target ‘build/app.out’ failed
    mingw32-make: *** [build/app.out] Error 1

    Reply
    1. Baoshi says:
      January 17, 2016 at 11:11 am

      Hi Ravi,
      You can locate /ld/eagle.app.v6.ld, there is a section
      MEMORY
      {
      ...
      irom0_0_seg : org = 0x40240000, len = 0x0fb000
      }

      Change len according to your module’s flash size. There are some sample values at the top of the file.

      Reply
  3. Ravi says:
    January 17, 2016 at 7:56 pm

    Hi Baoshi, Thank you for the reply. I will try that out and let you know. By the way, do you have a simple UART echo program for ESP8266? I am trying to read data on UART0 and echo it back to UART0.

    Reading the UART fails somehow fails with a fatal exception 28. I am partially using the UART.c file from the UART_TCP_PassThroughDemo project.

    Reply
  4. ALEXANDRE PINHEIRO says:
    April 25, 2016 at 12:38 pm

    Hi, great job! I have limited skills on C, and I’m trying to figure out how to output using printf the received message. I noticed that your code print one character at once (using the dsmg_putchar), but I’m having hard time to convert this to a usable string.

    Reply
  5. Rickson Dpenha says:
    August 27, 2016 at 12:48 pm

    Hello have u worked with wolfmqtt? It has SSL support

    Reply
  6. valmik thakar says:
    October 20, 2016 at 4:35 pm

    Hi I face issue like,
    xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: build/app1.out section `.text’ will not fit in region `iram1_0_seg’

    I tried to change length in ld flag and compile correctly device continuously reboot.
    I use RTOS 1.4.0 SDK.

    Reply
  7. zengfu says:
    December 8, 2016 at 1:58 pm

    I think the semaphore maybe be replaced by the event bit.

    Reply
  8. valmik thakar says:
    March 14, 2017 at 8:06 pm

    Hello,
    I have used this mqtt library for esp8266 project.
    And it works fine.
    but when I tried to subscribe on multiple topic with same client, failed to subscribe.
    so, This library can not support multiple subscription.

    Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Arduino ARM AVR Charger CNC Distance Sensor emWin ESP31 ESP32 ESP8266 FT230X GCC iPad JTAG LED Strip Makefile Maker Faire MF70 OLED Oscilloscope PCB PIR Sensor Pogo pin PWM Raspberry Pi RGB LED Rigol RTOS Saleae SEGGER Shopping SPI SSD1305 SSD1306 STM8 STM32 STM32Cube STM32CubeMX Storage TFT Tindie Tool USB Power VFD Workbench

Recent Posts

  • Arduino Redesigned – Maker UNO Review
  • Is ESP8266 I/O really 5V tolerant?
  • First sight into ESP32
  • ESP8266 MQTT client on RTOS
  • Maker Faire, Yearly Review, and Rant

Archives

  • March 2018
  • August 2016
  • December 2015
  • August 2015
  • July 2015
  • April 2015
  • February 2015
  • January 2015
  • December 2014
  • October 2014
  • July 2014
  • May 2014
  • March 2014
  • January 2014
  • December 2013
  • November 2013
  • August 2013
  • July 2013
  • May 2013
  • March 2013
  • January 2013
  • December 2012
  • November 2012
  • October 2012
  • September 2012
  • August 2012
  • July 2012
  • June 2012
  • May 2012

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
©2023 Digital Me | Design: Newspaperly WordPress Theme