This library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT v3.

For more information about MQTT, visit http://mqtt.org.

Download

The latest version of the library can be downloaded from GitHub.

Documentation

The library comes with a number of example sketches. See File > Examples > PubSubClient within the Arduino application.

Full API Documentation

Limitations

  • Only Quality of Service (QOS) 0 messaging is supported.
  • The maximum message size, including header, is 128 bytes by default. This is configurable.
  • The keepalive interval is set to 15 seconds by default. This is configurable.

Compatible Hardware

The library uses the Arduino Ethernet Client api for interacting with the underlying network hardware. This means it Just Works with a growing number of boards and shields, including:

The library cannot currently be used with hardware based on the ENC28J60 chip – such as the Nanode or the Nuelectronics Ethernet Shield. For those, there is an alternative library available – but I do not know what state that is in.

License

This code is released under the MIT License.

Change History

The complete change history is available on GitHub.

1.9
  • Do not split MQTT packets over multiple calls to _client->write()
  • API change: All constructors now require an instance of Client to be passed in.
  • Fixed example to match 1.8 api changes – dpslwk
  • Added username/password support – WilHall
  • Added publish_P – publishes messages from PROGMEM – jobytaffey
1.8
  • KeepAlive interval is configurable in PubSubClient.h
  • Maximum packet size is configurable in PubSubClient.h
  • API change: Return boolean rather than int from various functions
  • API change: Length parameter in message callback changed from int to unsigned int
  • Various internal tidy-ups around types
  • Able to specify server address by DNS name
1.7
  • Improved keepalive handling
  • Updated to the Arduino-1.0 API
1.6
  • Added ability to publish retained messages
1.5
  • Added default constructor
  • Fixed compile error when used with arduino-0021 or later
1.4
  • Fixed connection lost handling
1.3
  • Fixed packet reading bug
1.2
  • Fixed compile error when used with arduino-0016 or later
1.1
  • Reduced size of library
  • Added support for Will messagesClarified licensing – see LICENSE.txt
1.0
  • Only Quality of Service (QOS) 0 messaging is supported
  • The maximum message size, including header, is 128 bytes
  • The keepalive interval is set to 30 seconds
  • No support for Will messages
  1. pingback from knolleary » Blog Archive » CurrentCostuinoNovember 19, 2008

  2. pingback from knolleary » Blog Archive » Updated Client for MQTT libraryJanuary 29, 2009

  3. pingback from Delphi can do MQTT too!February 23, 2009

  4. pingback from Updated Arduino MQTT client « knollearyJuly 24, 2009

  5. john cohn • January 1, 2010

    Hello and happy new year ! !. I was wondering if you’d have a few minutes to help me think through how to get your MQTT client for the arduino working wiht the Asynclabs WiShield for 802.11 (http://asynclabs.com/wiki/index.php?title=WiShield_1.0) . The WiShield uses the uip TCP/IP stack.. not the one in the standard Ethernet.h used by the Arduino ethernet shields. I’ve been fiddling with your code to see if I can map over to the different IP stack, but I’m afraid it’s a little beyond me. A few minutes of coaching from you might get me there. Please let me know if you’re available to talk. Thanks !
    -jc

  6. nickJanuary 1, 2010

    Hi John – porting this library to other shields has been on my todo list for a while; so I’m happy to help if I can.

    I’ve had a quick look and it should be possible to do. The API provided by Ethernet.h is very simple; connect, read, write, disconnect, not much else. The trick will be figuring out how the equivalent functionality is surfaced by the WiShield library. The sample apps provided with WiShield should help do this.

    I’m back in the office next week; give me a shout on Sametime and we can take a close look.

  7. john cohn • January 2, 2010

    Nick,
    Will do .. I just set up a mtg for us on Monday.. let me know if the time’s OK. I look forward to speaking with you about this and some other schemes. Thanks !
    -jc

  8. MarkJanuary 3, 2010

    Hi
    Just wanted to say thanks for creating this client. Using this I have created a small web page that shows the temperature from a network connected Arduino. It is hosted on a tiny home server, so may take a few seconds to open….
    http://metphoto.homeunix.net/met_current/cgi-bin/ardtemp.pl

    I am no programmer, so could I ask for a small example of how to decode a message from a RSMB? I just cant quite get the code right to do this.

    Thanks
    Mark

  9. JerryJanuary 25, 2010

    Thanks for the MQTT client code Nick – I’ve been experimenting with this off and on for a month or two, using it with an Arduino duemilanove to demo MQTT to colleagues as a better way to read data from sensors than using the web server/Ethernet shield examples that are getting more coverage. BTW Mark’s PDF and project (link above) is a useful worked example, demonstrates the whole thing end to end and fills in some gaps in an unassuming kind of way.

  10. Dave NiceMarch 3, 2010

    Hi Nick,

    I’ve been using the MQTT library and I’ve got a couple of questions:

    If I lose my MQTT connection (e.g. unplug the network cable and wait for the library to realise it’s been disconnected), to get reconnected I have to call client.disconnect() first. Is this expected behaviour?

    Also, I have a 250ms pause at the end of my loop function. The effect of this is that client.loop() gets called less often. In your API doc it seems to indicate that I only need to call often enough to prevent the connection timing out and maintain my own preferred level of service on time to receive a message, is this correct?

    Thanks,

    Dave

  11. nickMarch 4, 2010

    Dave,

    #1 I haven’t done much with that scenario, so I couldn’t say for sure. There is no state cleared when you call disconnect, so it shouldn’t be necessary.

    #2 250ms will be fine. For a publishing-only client, you can get away with calling loop() once every keep-alive interval (fixed at 15secs). For a subscribed client, the same is true, but you will only get a message-arrived callback whilst in a call to loop() – it is up to you how timely you want the message delivery to be.

  12. pingback from Progress! « Nick Marshall – Final Year ProjectMarch 19, 2010

  13. pingback from chemicaloliver » MQTT, Arduino, Old Ammeters and Bandwidth MonitoringJune 13, 2010

  14. pingback from chemicaloliver » MQTT, Mosquitto and PHPJuly 3, 2010

  15. pingback from Updated Arduino MQTT Client « knollearyJuly 20, 2010

  16. pingback from MQTT, Mosquitto and PHP | chemicaloliverSeptember 4, 2010

  17. pingback from A Smarter Planet needs lightweight messaging | The lost outpostDecember 4, 2010

  18. pingback from MQ Telemetry Transport » Blog Archive » MQTT ported to the mbed platformDecember 20, 2010

  19. pingback from Prototyping – Arduino and Ubuntu | The lost outpostDecember 21, 2010

  20. Andy PiperDecember 27, 2010

    I found that this wouldn’t compile with current avr / Arduino 0021 IDE on Ubuntu. It was reporting an error avr/lib/gcc/../../avr/include/math.h:439: error: expected unqualified-id before ‘double’ (and a couple more compile issues related to that). I seem to have resolved it by commenting out #include “WConstants.h” in PubSubClient.cpp … you might also want to revisit the example you’ve posted here since the Ethernet library now requires SPI.h to be included. HTH :-)

  21. nickDecember 27, 2010

    Thanks Andy. Funnily enough, I discovered the very same thing in the last couple of hours myself. I will be pushing updates soon.

    Update: version 1.5 now available above.

  22. pingback from Updated Arduino MQTT Client « knollearyDecember 27, 2010

  23. pingback from Lightweight Messaging and Linux | The lost outpostJanuary 28, 2011

  24. pingback from Arduino, Wifly and MQTT « Nick Marshall | Final Major ProjectMay 15, 2011

  25. pingback from Nanode – a cheap networked arduino clone | MosquittoJune 8, 2011

  26. pingback from Arduinos, MQTT and Light levels - Matt Daubneys BlogSeptember 4, 2011

  27. pingback from MQTT Caller Display – Hacking the BT Caller Display 50 Serial Port | chemicaloliverOctober 2, 2011

  28. Lee Wenger • October 14, 2011

    Hi Nick,

    I tried to post a comment here yesterday about some issues running the library (and examples) with the Arduino 1.0 build – did you get it? I assume you probably have to approve comments before they get posted and thats why its not showing up – thats all cool – i’d just appreciate any help you might have to offer.

    I have another question for you – It looks like the library assumes that you’re running communications over ethernet – i’d be interested in your thoughts about running it over zigbee – ideally the communications protocol would be abstracted and any actual comms protocol could be substituted in as needed. In my case, i’d want to bridge from zigbee to ethernet at some bridge point but it would be terribly cool I think if I could publish content from my wireless sensor network that is only connected wirelessly via the xbee v2 modules but directly into mqtt which then get routed around and ultimately bridged into ethernet and out to the internet as necessary. The reverse case would also be helpful. My C skills seriously suck or i’d just attempt it myself – i’m trying to improve but it will be awhile before I can tackle something like this.

  29. Lee Wenger • October 14, 2011

    hmm – looks like the issue is that I can’t post the error output – I’ve tried to post it a couple times and seems to fail every time. I’m getting an error when I try and compile and upload to an arduino with the new Arduino 1.0 Beta. As I mentioned I’d give you the actual error output but your form here doesn’t seem to want to take it. All of the errors appear to stem from instantiating a virtual object somewhere within the library – “cannot declare field ‘PubSubClient::_client’ to be of abstract type ‘Client’ and then a number of errors that seem to be similarly related – …the following virtual functions are pure within ‘Client’ and then several. So it looks like the compiler used to allow you instantiate a virtual class and/or a class with virtual functions and now the compiler barfs on this. Just wondering if there are any easy ways to fix this?

    Thanks for the help – and seriously thanks for creating the library!

  30. nickOctober 14, 2011

    Hi Lee,
    Looks like your original comments with the error output went straight past moderation into the spam heap. Sorry about that.
    You need to grab the very latest code from github to get Arduino 1.0 Beta support – I’ve not done a zipped up release of that code yet.
    I had thought about making the library more agnostic of the transport, but ultimately I decided to keep the size down by dedicating it to one underlying library.
    MQTT itself does assume a TCP-based network layer beneath it, so with something like ZigBee a bit more work is needed to keep the same level of message assurance MQTT provides. This is where the MQTT-S protocol could come in – have a look on the docs page of mqtt.org – which is intended for the type of thing you describe.

    I’m hoping to do some more in this direction at some point.

  31. Lee Wenger • October 15, 2011

    Thanks Nick for speedy reply – that did the trick.

    I’ll read up on MQTT-S thanks for the pointer.

    Again -thanks for your effort on this library – definitely a worthy addition to the arduino collective.

    lw

  32. naxe • November 26, 2011

    Hi Nick
    Thanks Nick for your library .It works very well.
    I have a question about how to get the subscribe data form server and send out to serial port? The “void subscribe(topic)” do not have return data……

  33. nickNovember 26, 2011

    Hi Naxe,
    the call to subscribe() just sets up the subscription on the server; it doesn’t return a message. When the server sends your client a message, the callback function you provided in the constructor will get called.
    N

  34. naxe • November 28, 2011

    Thank you ,i get it……

  35. DougieFebruary 22, 2012

    I think your example would be improved by adding a couple of lines in the callback function to do something with the message from MQTT.

    So I added
    Serial.begin(9600);
    in the setup() function

    and
    void callback(char* topic, byte* payload, int length) {
    // handle message arrived
    Serial.println(“Callback”);
    Serial.print(“Topic:”);
    Serial.println(topic);
    Serial.print(“Length:”);
    Serial.println(length);
    Serial.print(“Payload:”);
    Serial.write(payload,length);
    Serial.println();
    }

    I’ve also changed the Ethernet.begin(mac, ip); to Ethernet.begin(mac); so that the Arduino running as a client gets a DHCP address. My MAC address was generated using the technique at [Nick says: URL removed as it linked to a dead domain] as I don’t like using DE:AD:BE:EF:FE:ED since it’s not unique.

  36. riddle • April 7, 2012

    Hi Nick,
    I just started playing with Arduino, could you give me some guidance on how can I use your library with Wifly Shield ? I am using Arduino Uno and SparkFun Wifly Shield. What I have done so far is I have successfully requested to a web site and get response using that shield.

  37. nickApril 7, 2012

    Hi, I’ve not done it myself, but it should be fairly straightforward.

    You need an updated version of the WiFly shield library, I think this is the one: https://github.com/dpslwk/WiFly

    There is also this fork of my library that may be needed – https://github.com/dpslwk/pubsubclient

    At some point, I’ll merge the changes back into this library.

  38. riddle • April 21, 2012

    Hi Nick,
    Thanks for the links. I’ve got it running and now getting more excited.

  39. Nick_Liu • May 10, 2012

    Hi Nick:

    It’s now MQTT can on the wifi shield ??

  40. pingback from RaspberryPi and MQTT Mosquitto | HumpA BlogJune 8, 2012

  41. Doug • June 9, 2012

    I’m getting the following when using arduino IDE 1.0.1 and compiling the basic example

    mqtt_basic.pde:-1: error: invalid conversion from ‘void (*)(char*, byte*, int)’ to ‘void (*)(char*, uint8_t*, unsigned int)’
    mqtt_basic.pde:-1: error: initializing argument 3 of ‘PubSubClient::PubSubClient(uint8_t*, uint16_t, void (*)(char*, uint8_t*, unsigned int))’

  42. nickJune 9, 2012

    Hi Doug. Yeah, I forgot to update the example when I made a minor api change in the last release. It’s fixed on github.

  43. Eddie • June 16, 2012

    You sure it’s fixed? I’m getting the same prob.. v1.8. Says it was updated 3 months ago.

  44. Eddie • June 16, 2012

    Example up the top compiles..

    Anyone tried using this code with cosm.com?

    https://cosm.com/docs/beta/mqtt/

  45. nickJune 16, 2012

    Yes, the version on this page is the same as the one on github which is newer than the version in the v1.8 release.

    I’ve used it with Cosm in the past, and as you’ll see from my recent blog post, I’ve been doing other MQTT things with Cosm.

  46. Eddie • June 16, 2012

    I’m a bit of a newbie to the scene.. How do I get meaningful values from the char* topic and byte* payload?

    I tried looping through the array but was nothing meaningful..

  47. Eddie • June 16, 2012

    Sorry disregard that last message. Worked it out :D

  48. Alessandro • June 21, 2012

    Could anybody post a quick example on using this library with Cosm?

    I’ve been able to test subscriptions from the arduino to a broker in my local network and to test.mosquitto.org, but not with api.cosm.com.

    1) I am using 216.52.233.121 (api.cosm.com)
    2) I call client.connect(“arduinoClient”) not sure if this is a problem
    3) It claims to connect (client.connect returns true), then I subscribe to “api_key/v2/feeds/myfeedid.csv”
    4) Nothing comes back in the callback

    I am certain the topic works since I can use it with mosquitto_sub.

    Any ideas?

    Thanks

    Alessandro

  49. ilium007 • June 22, 2012

    Eddie – it would have been nice of you had of posted how you ‘worked it out; for others who are trying to do the same thing !

    Can someone please tell me how to get from the byte array back into a meaningful string ?

  50. nickJune 22, 2012

    ilium007 – it depends what you mean by meaningful string.

    For the topic, it is already defined as a char* – a null-terminated string – so can be used as you would expect, such as pass to the Arduino String constructor.

    But the payload is not at all guaranteed to be null-terminated – as that entirely depends on what the publisher sent.

    There are plenty of string functions available for byte-arrays that are not null-terminated, for example strncmp for comparing strings of specified length:

    void callback(char* topic, byte* payload, unsigned int length) {
      if (length == 3 && strncmp(payload,"foo",3) {
         // Foo!
      }
    }
    

    If you want to use Arduino’s String object, then there is a extra step needed – as it doesn’t have a constructor that takes a byte-array and length. The extra step is to convert the byte array into a null-terminated char array.

    The expensive (but safe) way of doing this would be to allocate a new char array of length length+1, copy over the payload bytes and then set the last byte to NULL. You could then pass this array to the String constructor.

    There is an easier way of doing this, as long as length is not too big (for now, lets say under 100 – I won’t get into the whys of this here). In this instance, you can do the following:

    void callback(char* topic, byte* payload, unsigned int length) {
      // As long as length isn't too big, we can add a null to the payload:
      payload[length] = '\0';
      String strPayload = String((char*)payload);
    }
    

    This takes advantage of the fact that the client pre-allocates a large buffer for packets that is bigger than the payload that is returned in the callback. Setting payload[length] is safe to do as it is within the pre-allocated buffer.

    Hope that helps.

  51. ilium007 • June 23, 2012

    (Nick says: three quick-fire comments collapsed down into one)

    Cheers !! I have a had a play with all of the above but I am not sure what the line:

    payload[length] = '';

    is saying.

    Also, when I run the first example I get the error:

    “invalid conversion from ‘byte*’ to ‘const char*’

    This is what I have done with my callback function:

    void callback(char* topic, byte* payload, unsigned int length)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      
      if ((payload[0])==80 && (payload[1])==80)
      {
        lcd.print("PUMP:");
        if (payload[2]==48 && payload[3]==49)
        {
          lcd.print("ON");
          //turn on the pump here; set digital pin high to trigger SSR
    
        }
        else if (payload[2]==48 && payload[3]==48)
        {
          lcd.print("OFF");
          //turn off the pump here; set digital pin low to trigger SSR
        }
        else
        {
          lcd.print("NA");
        }
      }
      delay(5000);
      lcd.clear();
    }
    

    I am not sure if this is the best way to handle a very simple MQ type message protocol. ANy suggestions welcome. I am trying to write a simple protocol that I will use to measure water in my various water tanks and then turn on/off pumps and open/close solenoid valves as necessary.

    I should have added. At present to turn on a pump I would send a message:

    PP01

    to turn off:

    PP00

  52. nickJune 23, 2012

    ilium007,
    that first example should have been strncmp((char*)payload,"foo",3) – it needs the explicit cast to the right type.

    The payload[length] = ''; line is actually payload[length] = '\0';. This sets the byte immediately after the payload to the null byte – which allows payload to be treated as a null-terminated string.

    I would change your if statements to be something like:

    if (length == 4 && strncmp((char*)payload,"PP01",4)==0) {
      // turn pump on
    } else if (length == 4 && strncmp((char*)payload,"PP00",4)==0) {
      // turn pump off
    }
    // etc
    

    That said, I would suggest changing your topic structure slightly. Rather than have a single topic for all commands you want to send to the arduino, use a different topic for each device connected. For example:

    foo/pump1
    foo/solenoid1
    foo/pump2
    ...
    

    You can then subscribe to foo/#. You would then publish a simple ’0′ or ’1′ to the appropriate topic to signify off or on. You may even publish the messages with the ‘retained’ flag set, so that if the Arduino loses its connection and reconnects, it’ll get back the last known state of all the devices when it resubscribes.

    Following this approach means the callback would be something like:

    //Note the use of strcmp rather than strncmp
    // this is because topic is already a null-terminated
    // string.
    if (strcmp(topic,"foo/pump2")==0) { 
     if (payload[0] == '0') {
      // Turn off
     } else if (payload[0] == '1') {
      // Turn on
     }
    } // etc
    

    (Wrap your code in <pre></pre> tags)

    ((I’m going to collapse your comments down to a single one))

    (((I should probably create a mailing-list of something for this sort of discussion, to save space here)))

  53. ilium007 • June 24, 2012

    OK thanks. This has got me tearing my hair out ! I wasn’t brought up on C programming and I am having a hell of a time working out what data type I need to get these values in to publish to the MQTT queue from the Arduino.

    I have a Maxbotix sensor which I am getting a pulse width value (long) and converting into an int value through division to get a distance in cm. I assumed it would be easy to get this data type onto the queue via the publish method. I see it takes a topic as an array of characters but again I am stuck on the payload. It takes a byte array as the payload, as in, a NON null terminated array of bytes. How do I go from the int value to a byte array.

    Thanks

  54. ilium007 • June 24, 2012

    My bad – I have just re-read the API reference and I now see that the publish method can take a char* for topic (I’m cool with that) and a char* for payload. I just need to get my int into a char*

    I am sure this is dead simple – I just don’t know how to do it ! I have run out of pins on my EtherTen and I can’t run Ethernet, my maxbotix sensor, LCD shield and serial. Serial has had to lose out to the LCD so now my only method of debugging my code is via LCD and MQTT !

  55. nickJune 24, 2012

    ilium007 – check out the itoa C function:

    char payload[10];
    int i=1234; 
    itoa(i, payload, 10);
    
  56. ilium007 • June 24, 2012

    Invalid conversion from long int to char*

    I didnt even know there was a data type of ‘long int’

    This is my code:
    for(int i = 0; i < arraySize; i++)
    {
    digitalWrite(swPin, HIGH); //bring high for 21us to start MaxSonar ranging
    delayMicroseconds(39);
    digitalWrite(swPin, LOW);
    pulse = pulseIn(pwPin, HIGH);
    cm = pulse/58; //58uS per cm
    //rangeValue[i] = pulse/58;

    char payload[10];
    itoa(cm, payload, 10);

    mqttClient.publish("tanks/status",cm);

    delay(10);
    }

    I am trying to output the distance measurement in the MQTT message. pulse is initiated as ‘long’, cm is an int

  57. nickJune 24, 2012

    There’s lots of information on converting types on google… suggest you have a look there for now. Rather than debug your code here, I’ll mail you tomorrow.

  58. ilium007 • June 24, 2012

    Apologies. Thanks for the help so far.

  59. infohoundJuly 13, 2012

    Hi Nick. Thanks for writing and distributing this MQTT library for Arduino. Is there any way that you could post a quick Arduino example of how to print a received message (from a subscribed topic) using the callback function? I’ve reviewed the comments and documentation and am able to connect and publish messages, but just haven’t been able to quite figure this out. Thanks in advance for your time and help.

  60. nickJuly 13, 2012

    infohound, do you mean print the payload to Serial?

    Here are a couple examples that ought to work:

    // See caveats of this approach in comment #50
    void callback(char* topic, byte* payload, unsigned int length) {
      // As long as length isn't too big, we can add a null to the payload:
      payload[length] = '\0';
      String strPayload = String((char*)payload);
      Serial.println(strPayload);
    }
    
    void callback(char* topic, byte* payload, unsigned int length) {
      for (int i=0; i<length; i++) {
        Serial.print((char)payload[i]);
      }
      Serial.println();
    }
    
  61. infohoundJuly 14, 2012

    Thanks Nick, but unfortunately neither of those worked. I had tried the first suggestion when reading the comments previously and just tried it again (along w/ the other) after your response. Unfortunately, I still can’t get it to work. I can successfully connect, subscribe and publish messages but can’t seem to receive them. I keep getting an “Error: Connection timed out” message from the Mosquitto broker that I’m using to publish. Other clients are able to receive the published messages but I haven’t been able to figure this out. Thanks again for your help and I’ll keep plugging away at it. If you happen to think of something that may help please let me know. Thanks again.

  62. infohoundJuly 14, 2012

    Scratch that! I just got it. Thanks again for your help Nick!

  63. Des • August 9, 2012

    Is this likely to work easily with other Wifi shields? e.g.
    http://bit.ly/OUByca

    Thanks!

  64. nickAugust 12, 2012

    Hi Des – it should work with any WiFi shield whose library extends the Arduino Ethernet client library. Following that link to RobotShop.com, I couldn’t find any details on what libraries their shields use, so I cannot say for certain.

  65. Johan • August 14, 2012

    Hi Nick,

    Thanks alot for the effort, do you know whether your library supports the ethernet ENC28J60 chipset?

  66. nickAugust 14, 2012

    Hi Johan, there is a fork on github that claims support for that chipset (as is found on the Nanode, for example) – but I have to admit I haven’t kept up to date with where it has got to. https://github.com/njh/NanodeMQTT/

  67. Johan • August 14, 2012

    @Nick, thanks for the reply, I’ll give it a shot.

  68. Johan • August 14, 2012

    Hi Nick, tried, but Nanode with MQTT has severe space implications on my ATMega328. Is there no change that it might word with the EtherCard libaries that support ENC28J60? https://github.com/jcw/ethercard?

  69. nickAugust 15, 2012

    Hi Johan. The simple difference between the ENC28J60 hardware and the WizNet hardware used in the official shield is that WizNet implements the TCP layer of the networking stack for you, where as with the ENC28J60, you have to implement TCP yourself on the ATMega328.

    EtherCard, and older libraries for the ENC*, were intended for the simple request-response exchanges in HTTP. This meant their TCP implementation did not need to worry about multiple packet exchanges, or connections that lasted more than this simple exchange.

    MQTT requires a sustained TCP session, so requires more of TCP to be implemented.

    I see in the README for EtherCard there is experimental support for streamed data. Depending where that has got to and how reliable that is, then it might be feasible to port my library to use that as the underlying network layer. But that wouldn’t be a simple drop-in replacement and would require quite a lot of work.

    If at some point the EtherCard library was wrapped in a library that was API compatible with the official Ethernet library, then it would be easier to port.

  70. Josh Hawley • August 29, 2012

    Hey Nick,
    Whenever I publish from the Arduino I receive the message ~10 times on my client. I am attempting to publish sensor data so it can be viewed by other devices. Any ideas on a good process that I can use to narrow down where the message is getting duplicated?

    Setup:
    Moquitto MQTT Broker 1.0.2 cygwin (http://mosquitto.org)
    MqttDotNet library for .Net (http://sourceforge.net/projects/mqttdotnet/)
    Arduino Uno R3 with and Arduino Ethernet Shield
    This library as of 8/26/2012.

  71. nickAugust 30, 2012

    Hi Josh. I would start by grabbing something like IA92 (http://mqtt.org/wiki/doku.php/ia92) to subscribe to the topic. Using a second subscriber will confirm if the duplicate messages are coming from the publisher (arduino) or are an issue with the subscriber (.NET client).

    If IA92 also receives the 10 messages, then the issue is on the arduino side. The next thing to check is the logic in your code. Add some tracing (ie Serial.println) to verify how many times your code is really calling publish. If it is genuinely only calling publish once, then it starts to get a bit more involved. At that point, I’d use something like Wireshark to look at the network traffic to see what is happening at the MQTT level.

    Hope that helps – if you want to follow up, drop me an email (nick at this domain).

  72. Andrew TothOctober 9, 2012

    Nick,

    Nice work! Have this running on a Nanode connected to an LED message board vis RS232. Mode connectedness to come.

    Enjoying the projects on your site. Thanks for all your efforts.

  73. soilboy • October 22, 2012

    Hi

    Has anybody got this library to work with cosm? I have the same issue as Alessandro a few months ago but not sure If he had any comments.

    I can publish fine to a public broker but NOT cosm.

    Cheers

  74. nickOctober 23, 2012

    Hi Soilboy – I have just successfully connected to cosm and subscribed to a feed – so it is possible. I think the problem Alessandro, and presumably you, are hitting is to do with the maximum packet size the client supports.

    Cosm allows you to specify your api in two different ways; either as the username or prefixed to the topic.

    If you prefix it to the topic, then every publish you receive will include the full api key (as the full topic is included in the packet). The additional 48 characters of API key may be pushing the packet size over the limit.

    I found that by specifying the api key as the username, rather than prefixing it, then the messages arrived as expected. This does mean you cannot use different api keys for each topic you may want access to from the arduino.

    The alternative is to increase the value of MQTT_MAX_PACKET_SIZE in PubSubClient.h.

    Hope that helps.

  75. nickOctober 27, 2012

    Following up my last comment, although I could connect, it was always a fairly unstable connection. I’ll write a post soon, but if you want to use this library with Cosm, you should grab the latest version from github – not the current ‘released’ version (1.8). The Cosm broker does not like MQTT packets being split over multiple TCP packets – which this library was doing. I have changed the code to not do this and now the connection is solid.

  76. pingback from Updated Arduino Client for MQTT « knollearyNovember 11, 2012

  77. Josh Hawley • November 19, 2012

    What are the defaults for the smaller overloads on publish()? I assume that the length is calculated from the array that is passed in? Is retain set on or off by default? I looked in the API documentation, but it did not specify the default values.

  78. nickNovember 19, 2012

    Hi Josh – thanks for the question; Retain is false, and the payload is assumed to be a null-terminated string so its length can be determined. I’ve updated the API docs.

  79. Franz Garsombke • February 5, 2013

    Thanks for a great and useful framework!

    I was wondering if this framework works with the RedFly-Shield?

    https://github.com/watterott/RedFly-Shield
    http://www.watterott.com/en/Arduino-RedFly-Shield

    Thanks again.

    Franz Garsombke

  80. nickFebruary 5, 2013

    Hi Franz. I’m not aware of anyone using that shield with the library. I’ve had a quick look at its library and it looks like it implements the appropriate Client interface for it to work – but I’d want to try it out to be sure. I’m currently without a development environment thanks to a catastrophic attempt to upgrade Ubuntu on my laptop – once it’s back on its feet, I’ll have a closer look.

  81. Franz Garsombke • February 5, 2013

    Thanks for checking into the library Nick. I just received the RedFly (from Germany!) and have somebody soldering it up. I will let you know if it works or not. Your framework works perfectly with the Ethernet Shield.

    I’ve had a few catastrophic upgrades :) Now I never upgrade Ubuntu, and just start clean :)

    Take care.

    Franz

  82. Franz Garsombke • February 13, 2013

    Finally got the RedFly shield working. For some reason the RedFlyClient class extends Server which doesn’t make much sense to me.

    https://github.com/watterott/RedFly-Shield/blob/master/src/libraries/RedFly/RedFlyClient.h

    The PubSubClient input parameter is ‘Client’ so of course there is no matching function call. Doh!

    So, my guess is that it will not work without modifications to one of the libraries.

  83. Nuno • April 13, 2013

    Hi!

    I’m working with an Arduino project and I would like to abstract the communication layer using this MQTT library. I did not see in any place whether the library works or not with a bluetooth shield instead an ethernet. Where I can find more information?

    Thanks!

  84. nickApril 13, 2013

    Hi, I don’t know anyone using the library with a bluetooth shield, but the communication layer is already abstracted out so it should be possible. The library uses the Client interface for handling the network connection – by default it uses EthernetClient, but you can pass your own instance in one of the constructors. If you have, or can write, a library that uses that interface, it should work.

  85. Nuno • April 30, 2013

    Hi Nick,
    Thank you for your answer. To clarify, I don’t have a bluetooth shield like I said, I’m working with a bluetooth modem like this: https://www.sparkfun.com/products/10393 Basically the pins RX/TX are connected to the Arduino board.
    Right now, I have a mini-library called “SerialClient” that it’s an encapsulation of a SoftwareSerial object with the Client interface. I’m using a SoftwareSerial object to have the hardwareSerial for debugging purposes.
    With this solution I still have a problem because the bluetooth modem is seen as a SerialPort in my computer. I also developed a proxy to forward all bytes from the serial port (bluetooth) to the final MQTT server.

    It works very well, now I can finally talk with my project through a MQTT server :) Or if you want, it’s easy to switch to the HardwareSerial and this way the Arduino can be connected using the USB cable.

    Later I can publish the mini-library in Github if it’s useful to anyone.

    Thank you!

  86. David RyanJune 27, 2013

    Has anyone had much success with large messages publishing with publish_P? I’m trying to publish a message 2400 bytes. I’m using Serial1 to connect to a RN-XV WiFly module. I’m wondering if the default speed of 9600 is too slow and _client->write is over running the buffer?

    Thanks,
    David.

  87. David RyanJune 27, 2013

    I think I just answered my own question. I added a small delay between writing bytes in publish_P and it sent successfully.

    for (i=0;iwrite((char)pgm_read_byte_near(payload + i));
    delay(3);
    }

    Is there a better way of implementing this?

  88. nickJune 28, 2013

    Hi David, that’s a bit odd. I’m AFK at the moment… I’ll have a play when I’m back next week.

  89. Jerry • June 30, 2013

    I downloaded the latest Arduino Client Library from GitHub, its PubSubClient v1.9.1. Then I tried publishing to the Xively MQTT bridge. The problem is the topic name required by Xively is over-writing memory as the topic name is too long. For example,
    1. String topic = “test/foo/bar”; // Works
    2. String topic = “C11cF7Y3ahRP0X1h2T0j/v2/feeds/465951493.json”; // Works, max 20 char string
    3. String topic = ” C134cF7Y3aRP0X1h2T0j9Z7HCAecHc3901e2ZYHkKA5dkXQR/v2/feeds/465951493.json”; // FAILS due to 48 (first) alphanumeric field

    Xively MQTT bridge requires topic #3, but the first part is 48 chars and is over-writing memory in the Arduino PubSubClient library. Can someone please fix this? Thanks in advance!

  90. nickJune 30, 2013

    Hi Jerry,

    If you scroll back to comment #74 you’ll see this discussed. Either specify the 48 char API key as the username on connect (so you don’t need to include it in the topic of each publish) or increase the internal buffer size used to hold the packet in PubSubClient.h.

  91. Jerry • June 30, 2013

    An answer already give, perfect! It works well now in Xively. Here’s what worked for me …
    a. Used Port 1883 as Port 8883 would not authenticate with API_KEY
    b. Used API_KEY as Username, NULL as password on connect
    c. Topic had to start with ‘/’, e.g. “/v2/feeds/465951493.json”; as opposed to Xively docs which say “…subscribe to ‘API_KEY/v2/feeds/504.json’.”
    d. Didn’t need to change PubSubClient.h MQTT_MAX_PACKET_SIZE

    P.S. I scrolled through the post, better if I had searched for a keyword instead …

  92. John Lee • July 12, 2013

    I’m new to arduino. Has anyone tried connecting to MQTT by using a arduino WiFi shield? Is there any guides for me to edit it to make it compatible for arduino WiFi shield?

  93. nickJuly 12, 2013

    Hi John, you’ll see the Arduino WiFi shield is listed above in the Compatible Hardware section. I haven’t tried it personally, but it should just work by passing a WiFiClient instance to the PubSubClient constructor once the WiFi shield is connected to the network.

  94. John Lee • July 15, 2013

    Hi nick,

    Thank you for the guidelines. It can work with the arduino Wifi shield, but the arduino IDE required to be ver 1.0.2 instead of the new 1.0.5.

  95. nickJuly 15, 2013

    Hi John – that’s interesting. I’ll have a look at 1.0.5 and see what’s broken.

  96. Marcel • October 14, 2013

    A very promising development for the ENC28J60 board. It is a plugin-replacement of the stock Arduino Ethernet library for ENC28J60 shields.

    You can find it at https://github.com/ntruchsess/arduino_uip

    I could get the basic example running by just replacing ‘UIPEthernet.h’ instead of ‘Ethernet.h’

    I must add that for now it was not stable enough to run long, so I need to dig into the details of why stops after 1 or 2 messages

  97. Marcel • October 14, 2013

    seems like it is working after all. Hence as far as I can see the library at https://github.com/ntruchsess/arduino_uip works perfectly together.

    This makes room for very low cost arduino MQTT sensors!

  98. Tony Petchy • November 12, 2013

    Are there any plans to update the client library to include QOS of 1. Or, is this software considered mature and there is not going to be any major additions or improvements.

  99. nickNovember 12, 2013

    Hi Tony,

    funnily enough, there’s a pull request waiting for me to test that will allow the client to subscribe and receive QoS 1 messages.

    It does not add support for sending QoS 1, nor anything to do with QoS 2. These are not in the plan for this client as there is no reliable storage on the arduino, so we cannot provide proper QoS 1 or 2 semantics.

  100. Tony Petchy • November 14, 2013

    How long does the spec require the information be stored for QoS 1?

    What I need to do is make sure the data has been successfully transmitted and received. I do not have to verify anyone actually consumed the data, I just have to know it is/was available (that sounds like QoS 1). I guess I could subscribe to the topic and wait for the broker to send it back to me.

  101. nickNovember 14, 2013

    To properly assure qos 1 delivery, the client needs to store the message until it receives the acknowledgement from the server. This allows it to resend the message if it does not get that ack.

    By ‘store’, that could simply mean in memory, or in some non-volatile storage.

    If it is in memory only, then it will be lost if the Arduino resets. It also uses up scarce memory.

    If you have an SD card shield, that could provide non-volatile storage.

    Sticking to qos 0, doing the subscribe-to-verify trick would work.

  102. leave a comment

    You must be logged in to post a comment.