Arduino library for MQTT support

Overview

Adafruit MQTT Library Build Status

Arduino library for MQTT support, including access to Adafruit IO. Works with the Adafruit FONA, Arduino Yun, ESP8266 Arduino platforms, and anything that supports Arduino's Client interface (like Ethernet shield).

See included examples for how to use the library to access an MQTT service to publish and subscribe to feeds. Note that this does not support the full MQTT spec but is intended to support enough for QoS 0 and 1 publishing.

Depends on the following other libraries depending on the target platform:

Future todos:

  • Subscription callbacks

  • remove watchdog

Compatibility

MCU Tested Works Doesn't Work Not Tested Notes
Atmega328 @ 16MHz X
Atmega328 @ 12MHz X
Atmega32u4 @ 16MHz X
Atmega32u4 @ 8MHz X
ESP8266 X
Atmega2560 @ 16MHz X
ATSAM3X8E X
ATSAM21D X
ATSAMD51J20 X
ATtiny85 @ 16MHz X
ATtiny85 @ 8MHz X
Intel Curie @ 32MHz X
STM32F2 X
  • ATmega328 @ 16MHz : Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini
  • ATmega328 @ 12MHz : Adafruit Pro Trinket 3V
  • ATmega32u4 @ 16MHz : Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0
  • ATmega32u4 @ 8MHz : Adafruit Flora, Bluefruit Micro
  • ESP8266 : Adafruit Huzzah
  • ATmega2560 @ 16MHz : Arduino Mega
  • ATSAM3X8E : Arduino Due
  • ATSAM21D : Arduino Zero, M0 Pro
  • ATSAMD51J20: Adafruit PyPortal
  • ATtiny85 @ 16MHz : Adafruit Trinket 5V
  • ATtiny85 @ 8MHz : Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
Issues
  • Failed to build with ESP8266 V2.4

    Failed to build with ESP8266 V2.4

    After upgrading vom ESP Version 2.3 to 2.4 MQTT_Library (0.17.0) failed to build with following errors:

    Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp: In member function 'virtual bool Adafruit_MQTT_Client::sendPacket(uint8_t*, uint16_t)': /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: error: no matching function for call to 'min(uint16_t&, int)' uint16_t sendlen = min(len, 250); ^ /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: note: candidates are: In file included from /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/algorithm:62:0, from /Users/joerg/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.0/cores/esp8266/Arduino.h:240, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h:25, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h:26, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:22: /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:4226:5: note: template<class _Tp, class _Compare> _Tp std::min(std::initializer_list<_Tp>, _Compare) min(initializer_list<_Tp> __l, _Compare __comp) ^ /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:4226:5: note: template argument deduction/substitution failed: /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: note: mismatched types 'std::initializer_list<_Tp>' and 'short unsigned int' uint16_t sendlen = min(len, 250); ^ In file included from /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/algorithm:62:0, from /Users/joerg/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.0/cores/esp8266/Arduino.h:240, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h:25, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h:26, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:22: /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:4221:5: note: template _Tp std::min(std::initializer_list<_Tp>) min(initializer_list<_Tp> __l) ^ /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:4221:5: note: template argument deduction/substitution failed: /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: note: mismatched types 'std::initializer_list<_Tp>' and 'short unsigned int' uint16_t sendlen = min(len, 250); ^ In file included from /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/algorithm:61:0, from /Users/joerg/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.0/cores/esp8266/Arduino.h:240, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h:25, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h:26, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:22: /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algobase.h:239:5: note: template<class _Tp, class _Compare> const _Tp& std::min(const _Tp&, const _Tp&, _Compare) min(const _Tp& __a, const _Tp& __b, _Compare __comp) ^ /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algobase.h:239:5: note: template argument deduction/substitution failed: /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: note: deduced conflicting types for parameter 'const _Tp' ('short unsigned int' and 'int') uint16_t sendlen = min(len, 250); ^ In file included from /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/algorithm:61:0, from /Users/joerg/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.0/cores/esp8266/Arduino.h:240, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT.h:25, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.h:26, from /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:22: /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algobase.h:193:5: note: template const _Tp& std::min(const _Tp&, const _Tp&) min(const _Tp& __a, const _Tp& __b) ^ /Users/joerg/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algobase.h:193:5: note: template argument deduction/substitution failed: /Users/joerg/Documents/Arduino/libraries/Adafruit_MQTT_Library/Adafruit_MQTT_Client.cpp:84:38: note: deduced conflicting types for parameter 'const _Tp' ('short unsigned int' and 'int') uint16_t sendlen = min(len, 250); ^ exit status 1 Fehler beim Kompilieren für das Board Generic ESP8266 Module.

    opened by cyba3r 15
  • Better ping handling

    Better ping handling

    This fixes pings discarding publish messages by always checking for a PUBLISH packet when inside processPacketsUntil. This ensures topic messages will always get handled even if we're pinging.

    Also found a bug in Adafruit_MQTT_Client::readPacket which would actually read a byte rather than just returning. This would cause it to fail to read the next packet as the packet type byte had already been read.

    I suspect these changes will address issues #141 , #132 , and #83 . I have not tried reproducing them though to verify.

    opened by Fapiko 13
  • Packet Length Issues

    Packet Length Issues

    there seem to be a couple issues with the publish packet length. currently the payload seems to be limited to 128 chars. i think the problem is related to length being stored as uint16_t, and sent as a uint8_t: https://github.com/adafruit/Adafruit_MQTT_Library/blob/master/Adafruit_MQTT.cpp#L517

    also, maybe we could make publish return error codes, and generalize the error code printer? that way we could notify the user of the buffer length limit?

    opened by toddtreece 11
  • topic lenght - current code only reads the LSB part

    topic lenght - current code only reads the LSB part

    https://github.com/adafruit/Adafruit_MQTT_Library/blob/974f4b8713a83d01b040a0d23b798d3f2978d990/Adafruit_MQTT.cpp#L464

    would result in an error if the topicname is larger than 255 bytes

    opened by jwende 10
  • Buffer overflow in publishPacket

    Buffer overflow in publishPacket

    The function uint16_t Adafruit_MQTT::publishPacket has buffer overflow if you send a packet that is larger than the MAXBUFFERSIZE (topic len + data len).

    // as per http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
    uint16_t Adafruit_MQTT::publishPacket(uint8_t *packet, const char *topic,
                                         uint8_t *data, uint16_t bLen, uint8_t qos) {
      uint8_t *p = packet;
      uint16_t len=0;
    
      // calc length of non-header data
      len += 2;               // two bytes to set the topic size
      len += strlen(topic); // topic length
      if(qos > 0) { 
        len += 2; // qos packet id
      }
      len += bLen; // payload length
    
      // Now you can start generating the packet!
      p[0] = MQTT_CTRL_PUBLISH << 4 | qos << 1;
      p++;
    
      // fill in packet[1] last
      do {
        uint8_t encodedByte = len % 128;
        len /= 128;
        // if there are more data to encode, set the top bit of this byte
        if ( len > 0 ) {
          encodedByte |= 0x80;
        }
        p[0] = encodedByte;
        p++;
      } while ( len > 0 );
    
      // topic comes before packet identifier
      p = stringprint(p, topic);
    
      // add packet identifier. used for checking PUBACK in QOS > 0
      if(qos > 0) {
        p[0] = (packet_id_counter >> 8) & 0xFF;
        p[1] = packet_id_counter & 0xFF;
        p+=2;
    
        // increment the packet id
        packet_id_counter++;
      }
    
      memmove(p, data, bLen);
      p+= bLen;
      len = p - packet;
      DEBUG_PRINTLN(F("MQTT publish packet:"));
      DEBUG_PRINTBUFFER(buffer, len);
      return len;
    }
    

    As you can see from the code there isn't any check if we already went past the packet size and there fore we write over the boundaries.

    bug 
    opened by pakokol 9
  • Adafruit_MQTT::publishPacket: Protect against memory corruption.

    Adafruit_MQTT::publishPacket: Protect against memory corruption.

    Fixes https://github.com/adafruit/Adafruit_MQTT_Library/issues/109 Fixes https://github.com/adafruit/Adafruit_MQTT_Library/issues/122

    After spending a long time pulling my hair to understand why I was hitting a panic when attempting to read from my registered subscriptions, I found out that the subscriptions member of the Adafruit_MQTT instance was corrupted. :(

    Turns out the memory corruption was caused by my publish call, where the payload I was providing was bigger than the allocated space in the buffer for construction of the packet (see buffer[MAXBUFFERSIZE]).

    To protect myself from ever making this mistake again, I am proposing a simple logic in publishPacket where instead of silently corrupting memory, the code uses as much payload as it can fit in the available space. By seeing the truncated payload, user can decide whether he/she should 1)break it up into different topics, 2) put the payload on a diet, or 3) increase MAXBUFFERSIZE.

    ====

    • Describe the scope of your change--i.e. what the change does and what parts of the code were modified. This will help us understand any risks of integrating the code.

    This pull requests improves the handling of buffer for packet creation of Adafruit_MQTT::publishPacket. It adds argument maxPacketLen to keep track of how much space is available in buffer.

    • Describe any known limitations with your change. For example if the change doesn't apply to a supported platform of the library please mention it.

    This change is not modifying the sizes of any buffers. Instead, it truncates the payload to avoid memory corruption of the class Adafruit_MQTT by keeping packet creation from going beyond MAXBUFFERSIZE.

    • Please run any tests or examples that can exercise your modified code. We strive to not break users of the code and running tests/examples helps with this process.

    See this gist with an example code where a packet has a payload that exceeds MAXBUFFERSIZE and corrupts packet_id_counter and subscriptions of the Adafruit_MQTT instance.

    See comments below that gist with the crash and stack trace of code above, where memory is corrupted and the LoadProhibited exception takes place.

    Lastly, see the comment that follows with the proposed modification, where the same code simply gets the payload truncated instead of allowing memory to get messed up.

    opened by flavio-fernandes 8
  • "Dropped a packet" when sending more than once per second

    • Arduino board: NodeMCU (ESP8266)
    • Arduino IDE version: 1.8.5
    • Library version: 0.20.3

    On my Ubuntu 18.04 laptop, I installed mosquito and ran the following script:

    while true; do mosquitto_pub -t robot/commands -m `date +%s%N`; sleep 0.5; done;
    

    Then on the ESP8266 I'm pretty much running the mqtt_esp8266_callback example, modified to connect to my WiFi, my local Mosquito broker, and subscribe to my topic rather than then ones in the example.

    If I run it at a one second interval, it's fine, but if I run it with anything less, I get the output below (debugging enabled). On Wireshark everything looks completely normal.

    Read data:		0 [0x30], 
    Packet Type:		0 [0x30], 
    Read data:		# [0x23], 
    Packet Length:	35
    Read data:		  [0x00],   [0x0E], r [0x72], o [0x6F], b [0x62], o [0x6F], t [0x74], / [0x2F], 
    	c [0x63], o [0x6F], m [0x6D], m [0x6D], a [0x61], n [0x6E], d [0x64], s [0x73], 
    	1 [0x31], 5 [0x35], 3 [0x33], 7 [0x37], 0 [0x30], 2 [0x32], 0 [0x30], 3 [0x33], 
    	9 [0x39], 7 [0x37], 9 [0x39], 7 [0x37], 9 [0x39], 7 [0x37], 7 [0x37], 7 [0x37], 
    	8 [0x38], 0 [0x30], 9 [0x39], 
    Dropped a packet
    

    For comparison, this is what it looks like with a correctly read packet:

    Read data:		0 [0x30], 
    Packet Type:		0 [0x30], 
    Read data:		# [0x23], 
    Packet Length:	35
    Read data:		  [0x00],   [0x0E], r [0x72], o [0x6F], b [0x62], o [0x6F], t [0x74], / [0x2F], 
    	c [0x63], o [0x6F], m [0x6D], m [0x6D], a [0x61], n [0x6E], d [0x64], s [0x73], 
    	1 [0x31], 5 [0x35], 3 [0x33], 7 [0x37], 0 [0x30], 2 [0x32], 0 [0x30], 9 [0x39], 
    	4 [0x34], 3 [0x33], 9 [0x39], 2 [0x32], 4 [0x34], 1 [0x31], 4 [0x34], 7 [0x37], 
    	0 [0x30], 0 [0x30], 6 [0x36], 
    Packet len: 37
    	0 [0x30], # [0x23],   [0x00],   [0x0E], r [0x72], o [0x6F], b [0x62], o [0x6F], 
    	t [0x74], / [0x2F], c [0x63], o [0x6F], m [0x6D], m [0x6D], a [0x61], n [0x6E], 
    	d [0x64], s [0x73], 1 [0x31], 5 [0x35], 3 [0x33], 7 [0x37], 0 [0x30], 2 [0x32], 
    	0 [0x30], 9 [0x39], 4 [0x34], 3 [0x33], 9 [0x39], 2 [0x32], 4 [0x34], 1 [0x31], 
    	4 [0x34], 7 [0x37], 0 [0x30], 0 [0x30], 6 [0x36], 
    Looking for subscription len 14
    Found sub #0
    Data len: 19
    Data: 1537020943924147006
    
    opened by pepijndevos 8
  • Fona MQTT example with esp8266

    Fona MQTT example with esp8266

    hello, I am working on a project that includes sim800l accessing adafruit MQTT .it works fine with an arduino .my project need to use esp8266 12E with sim800l. I know esp8266 can be use standalone for MQTT but i need to use it as mcu for gsm module. Fona MQTT example shows this error"Error compiling for board NodeMCU 1.0 (ESP-12E Module)" . I am new to arduino or esp8266 , i hope this is a relevant problem.What am I doing wrong here,is there any alternative way to work with esp8266 with sim800l for accessing Adafruit MQTT?

    opened by kamrulroky 7
  • Publish data value with a historical timestamp?

    Publish data value with a historical timestamp?

    Hi there,

    I'm combining a Huzzah esp8266 with a HDC1008 and a photoresistor.

    WiFi uses lots of battery so my hope was to be able to store on the esp8266 a series of data points with timestamps and then when the memory was running low or the chip's battery voltage appears to be dropping too low, publish the data points with their historical timestamps to Adafruit IO feeds.

    Publish() seems to only take one value. Is there any way to do what I'm describing?

    opened by theschles 7
  • Examples are incorrect

    Examples are incorrect

    The example file contain an error:

    In verify Fingerpint

    if (!client.connect(host, AIO_SERVERPORT)) { Serial.println("Connection failed. Halting execution."); while(1); }

    fails if you don't first set the client fingerprint using:

    Serial.printf("Using fingerprint '%s'\n", fingerprint); client.setFingerprint(fingerprint);

    opened by Fredfishface 6
  • mqtt.connect() throws Exception (3) rst cause:2, boot mode:(1,6)

    mqtt.connect() throws Exception (3) rst cause:2, boot mode:(1,6)

    Hi,

    I'm using my good old Adafruit Huzzah ESP8266 to connect to a mqtt broker via wifi. The strange thing is, it used to work! But i left the project alone for 3 - 4 months, and after coming back / updating the Arduino IDE to 1.6.6 it stopped working. The mqtt.connect suddenly throws the exception below. Anything changed on the Adafruit Mqtt end? I now use Adafruit MQTT Libray 0.16.2 Maybe i need to update the firmware on the ESP8266 ?

    Connecting to MQTT... 
    
    Exception (3):
    epc1=0x4000bf3c epc2=0x00000000 epc3=0x00000000 excvaddr=0x402341ec depc=0x00000000
    
    ctx: cont 
    sp: 3fff0440 end: 3fff0660 offset: 01a0
    
    >>>stack>>>
    3fff05e0:  3fffdad0 0000001c 3ffef578 4020654d  
    3fff05f0:  3ffe88c1 3ffeeab8 3ffeeab8 402060ce  
    3fff0600:  3ffe85e5 00000000 3ffef578 40206578  
    3fff0610:  3ffeea78 3ffeea7c 3ffef578 3ffef634  
    3fff0620:  00000003 3ffeeab8 3ffef578 40202690  
    3fff0630:  3fffdad0 00000000 3ffef62c 402026cd  
    3fff0640:  3fffdad0 00000000 3ffef62c 40207074  
    3fff0650:  feefeffe feefeffe 3ffef640 40100718  
    <<<stack<<<
    
     ets Jan  8 2013,rst cause:2, boot mode:(1,6)
    
    
     ets Jan  8 2013,rst cause:4, boot mode:(1,6)
    
    wdt reset
    

    This is my sketch

    /**
       Get temperature and humidity from DHT-11 sensor (every xx-seconds) and publish it to an MQTT topic via wifi.
       @Author: Rino van Wijngaarden
    */
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <DHT.h>
    #include "Adafruit_MQTT.h"
    #include "Adafruit_MQTT_Client.h"
    
    #define WLAN_SSID         "<ssid_here>"
    #define WLAN_PASS         "<password_here>"
    #define MQTT_MY_SERVER    "<ip_of_mqtt_broker_here>""
    #define MQTT_SERVERPORT  1883
    #define MQTT_MY_USERNAME    ""
    #define MQTT_MY_PASSWORD    ""
    #define DHTTYPE DHT11
    #define DHTPIN  2
    
    // Store the MQTT server, username, and password in flash memory.
    // This is required for using the Adafruit MQTT library.
    const char PROGMEM MQTT_SERVER[]  = MQTT_MY_SERVER;
    const char PROGMEM MQTT_USERNAME[] = MQTT_MY_USERNAME;
    const char PROGMEM MQTT_PASSWORD[] = MQTT_MY_PASSWORD;
    const char PROGMEM MQTT_DHT11_TEMP_FEED[] = "/home/bg/tuinhuis/temperature";
    const char PROGMEM MQTT_DHT11_HUMIDITY_FEED[] = "/home/bg/tuinhuis/humidity";
    const char PROGMEM MQTT_BATTERY_VOLTAGE_FEED[] = "/home/bg/tuinhuis/battery";
    
    // ADC_MODE(ADC_VCC);
    WiFiClient wifiClient;
    Adafruit_MQTT_Client mqtt(&wifiClient, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
    Adafruit_MQTT_Publish dht11TempPublish = Adafruit_MQTT_Publish(&mqtt, MQTT_DHT11_TEMP_FEED);
    Adafruit_MQTT_Publish dht11HumidityPublish = Adafruit_MQTT_Publish(&mqtt, MQTT_DHT11_HUMIDITY_FEED);
    Adafruit_MQTT_Publish batteryVoltagePublish = Adafruit_MQTT_Publish(&mqtt, MQTT_BATTERY_VOLTAGE_FEED);
    
    // Initialize DHT sensor
    // NOTE: For working with a faster than ATmega328p 16 MHz Arduino chip, like an ESP8266,
    // you need to increase the threshold for cycle counts considered a 1 or 0.
    // You can do this by passing a 3rd parameter for this threshold.  It's a bit
    // of fiddling to find the right value, but in general the faster the CPU the
    // higher the value.  The default for a 16mhz AVR is a value of 6.  For an
    // Arduino Due that runs at 84mhz a value of 30 works.
    // This is for the ESP8266 processor on ESP-01
    DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266
    
    void connectToMQTT();
    void connectToWifi();
    boolean getSensorData();
    void publishDataToMQTT();
    
    float humidity, tempC, hic;  // Values read from sensor
    float voltage;
    String webString = "";   // String to display
    // Generally, you should use "unsigned long" for variables that hold time
    unsigned long dhtPreviousMillis = 0;        // will store last temp was read
    const long dhtInterval = 2000;              // interval at which to read sensor
    
    
    void setup(void)
    {  
      // You can open the Arduino IDE Serial Monitor window to see what the code is doing
      Serial.begin(115200);  // Serial connection from ESP-01 via 3.3v console cable
      delay(2);
      dht.begin();           // initialize temperature sensor
      connectToWifi();
    }
    
    void loop(void)
    {
      if (getSensorData()) {
        // Ensure the connection to the MQTT server is alive (this will make the first
        // connection and automatically reconnect when disconnected).
        connectToMQTT();
    
        publishDataToMQTT();
        
        Serial.print("Publish done. Sleeping now");
        ESP.deepSleep(60000000, WAKE_RF_DEFAULT); // Sleep for 60 seconds// note:  (GPIO16 needs to be tied to RST (and 5v) to wake from deepSleep.)
      }
    
    }
    
    
    void publishDataToMQTT()  {
      if (mqtt.connected()) {
        Serial.print("Trying to publish data to mqtt ...");
        if (!batteryVoltagePublish.publish(voltage)) {
          Serial.println(F("Publish to mqtt/battery failed"));
        } else {
          if (!dht11TempPublish.publish(hic)) {
            Serial.println(F("Publish to mqtt/temp failed"));
          } else {
            if (!dht11HumidityPublish.publish(humidity)) {
              Serial.println(F("Publish to mqtt/humidity failed"));
            }
          }
        }
      }
    }
    
    boolean getSensorData() {
      // Wait at least 2 seconds seconds between measurements.
      // if the difference between the current time and last time you read
      // the sensor is bigger than the interval you set, read the sensor
      // Works better than delay for things happening elsewhere also
      unsigned long currentMillis = millis();
    
      if (currentMillis - dhtPreviousMillis >= dhtInterval) {
        // save the last time you read the sensor
        dhtPreviousMillis = currentMillis;
    
        // Reading temperature for humidity takes about 250 milliseconds!
        // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
        humidity = dht.readHumidity();          // Read humidity (percent)
        tempC = dht.readTemperature(false);     // Read temperature as Celsius
        // Check if any reads failed and exit early (to try again).
        if (isnan(humidity) || isnan(tempC)) {
          Serial.println("Failed to read from DHT sensor!");
          return false;
        }
        // Compute heat index in Celsius (isFahreheit = false)
        hic = dht.computeHeatIndex(tempC, humidity, false);
    
        voltage = (ESP.getVcc()) / 1000.0;
        return true;
      }
      return false;
    }
    
    
    void connectToWifi(void) {
      // Connect to WiFi network
      WiFi.persistent(false);
      WiFi.disconnect(true);
      WiFi.begin(WLAN_SSID, WLAN_PASS);
      Serial.print("\n\r \n\rConnecting to wifi ....");
    
      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(WLAN_SSID);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());
    }
    
    // Function to connect and reconnect as necessary to the MQTT server.
    // Should be called in the loop function and it will take care if connecting.
    void connectToMQTT() {
      int8_t ret;
    
      // Stop if already connected.
      if (mqtt.connected()) {
        Serial.print("Already connected to MQTT");
        return;
      }
    
      Serial.print("Connecting to MQTT... ");
      uint8_t retries = 3;
      while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
        Serial.println(mqtt.connectErrorString(ret));
        Serial.println("Retrying MQTT connection in 5 seconds...");
        mqtt.disconnect();
        delay(5000);
        retries--;
        if (retries == 0) {
           // basically die and wait for WDT to reset me
           while (1);
        }           
        if (WiFi.status() != WL_CONNECTED) {
          connectToWifi();
        }
      }
      Serial.println("MQTT Connected!");
    }
    
    opened by rwijngaa 6
  • In several minitues my device always disconnect but connect back immediately

    In several minitues my device always disconnect but connect back immediately

    as the title saying ,I dont want to receice this disconnected message(I use $SYS topic to listen) because it didn't disconnect actually,I just want the disconnect message when truely disconnecting happened.

    opened by dirty-paper 1
  • packet_id_counter incrementing even if packet is dropped

    packet_id_counter incrementing even if packet is dropped

    Hello! I found that during the publish routine (bool Adafruit_MQTT::publish(...)), using QoS = 1, the packet_id_counter variable gets incremented even if the length check fails. Therefore, if a package is dropped, the counter adds one, but the broker counter doesn't, so it perpetually fails the packnum != packet_id_counter check because of an offset in these two counters.

    This would make it so the microcontroller would incorrectly assume that it's failing every publish, making it so you couldn't send multiple messages during one MQTT connection using QoS > 0 if even a single publish message is dropped.

    I'm using an ESP32 connected to a SIM800 module, and sending messages to a public HiveMQ topic.

    opened by eguarda 0
  • connection closed: Error: read ECONNRESET

    connection closed: Error: read ECONNRESET

    Issue:

    Tried to upload data to a MQTT broker (local network; IObroker) but failed to update a value which was writeable in a first try. When using a different MQTT client (Windows based standalone program), I was able to change this value without issue. I also could see my ESP8266 client connecting to the brokar and - according to the feedback in the arduino program - update/broadcast the vaalue on the broker, which was/is false.

    I monitored the logfile on the MQTT server side and always found the following log details whenever my ESP client tried to connect and change a value:

    2021-12-30 18:19:52.967  - info: mqtt.0 (3366) Client [] connected with secret 1640884792963_6139
    2021-12-30 18:20:55.447  - info: mqtt.0 (3366) Client [] reconnected. Old secret 1640884792963_6139. New secret 1640884855445_8033
    2021-12-30 18:21:57.413  - info: mqtt.0 (3366) Client [] connection closed: Error: read ECONNRESET
    2021-12-30 18:21:57.878  - info: mqtt.0 (3366) Client [] connected with secret 1640884917876_1207
    

    Solution and possible explanation: To me it looks like the Adafruit library tries to keep the connection and stores some values in memory to achive this. However, my ESP8266 calls the function ESP.deepSleep() after submitting a value, is reset and then starts from scratch - and something happens here which I can't explain. Maybe the server also tries to keep the connection which is breaking up in an undesired way when the client goes into deep sleep mode.

    The solution however is simple: Add mqtt.disconnect(); before calling deep sleep to close the connection in the correct way, which will not only result in the error in the log going away but also the value finally be published on the MQTT server

    mqtt.disconnect();
    ESP.deepSleep(120 * 1000000); // deep sleep for 120 secs
    
    

    Maybe this problem and the solution could be added to the documentation as I am sure that a lot of people use MQTT on an ESP8266 to send data points to a server while keeping the ESP in deep sleep to conserver energy (and run them on battery).

    opened by becks0815 0
  • Client disconected due protocol error when counting PUBLISH packets from 0

    Client disconected due protocol error when counting PUBLISH packets from 0

    • Arduino board: ESP8266 (LoLin NodeMcu v3)
    • Adafruit_MQTT_library: 2.4.2
    • MQTT Server: Eclipse mosquitto 2.0.12

    Hello, I discovered strange problem during publishing messages. Every first PUBLISH packet gets no response and additionally server closes connection with:

    Client 7879f4a.... disconnected due to protocol error.

    ...when packets are counted from 0. When I set packet_id_counter variable initially to 1 in Adafruit_MQTT::Adafruit_MQTT, everything works OK

    Adafruit_MQTT::Adafruit_MQTT(const char *server, uint16_t port, const char *cid,
                                 const char *user, const char *pass) {
      servername = server;
      portnum = port;
      clientid = cid;
      username = user;
      password = pass;
    
      // reset subscriptions
      for (uint8_t i = 0; i < MAXSUBSCRIPTIONS; i++) {
        subscriptions[i] = 0;
      }
    
      will_topic = 0;
      will_payload = 0;
      will_qos = 0;
      will_retain = 0;
    
      keepAliveInterval = MQTT_CONN_KEEPALIVE;
    
      // changed code
      packet_id_counter = 1;
    }
    

    This is also related to QOS level. packet_id_counter can be set to 0 but only when QOS 0 is used.

    I suspect that this is exact same case as described in MQTT docs:

    SUBSCRIBE, UNSUBSCRIBE, and PUBLISH (in cases where QoS > 0) Control Packets MUST contain a non-zero 16-bit Packet Identifier [MQTT-2.3.1-1].

    opened by apsite 5
  • Dynamically Assigning Adafruit IO credentials to Adafruit MQTT  object

    Dynamically Assigning Adafruit IO credentials to Adafruit MQTT object

    • Arduino board: ESP8266

    • Arduino IDE version (found in Arduino -> About Arduino menu): 1.8.16

    • List the steps to reproduce the problem below (if possible attach a sketch or copy the sketch code in too): LIST REPRO STEPS BELOW I want to be able to dynamically assign my MQTT credentials. I want to store them in a file then read them in the setup function and assign them to my Adafruit MQTT object. I have looked through the library files but I can't find a way to do it.

    In short, I want to be able to change my Adafruit io credentials without having to change them manually from the code.

    Thank you.

    opened by Pius171 0
  • Message length limit when publishing

    Message length limit when publishing

    Through the sketch in the library I'm trying to publish the following message {"unique_id": "TAVERNETTA-temperature","device_class": "temperature", "name": "TAVERNETTA Temperature", "state_topic": "homeassistant/sensor/TAVERNETTA/state", "unit_of_measurement": "°C", "value_template": "{{ value_json.temperature}}"}, but the message that arrives is truncated with a length of 147 characters.

    I'm pretty sure I made some mistakes, but I can't figure it out.

    Any suggestions?

    opened by mikycol 3
Releases(2.4.2)
Owner
Adafruit Industries
Adafruit Industries
A library to simplify the process of subscribing and publishing data to Antares IoT Platform through MQTT on ESP8266.

Antares ESP8266 MQTT A Library to simplify the process of MQTT publication and subscription to Antares IoT Platform using ESP8266. This library works

null 6 Mar 9, 2022
Arduino Arduino library for the CloudStorage server project. The library provides easy access to server-stored values and operations.

Arduino-CloudStorage Arduino/ESP8266 library that allows you to easly store and retreive data from a remote (cloud) storage in a key/value fashion. Cl

Gil Maimon 7 Jan 30, 2022
ESP8266 MQTT Sharp-fu-y30 air purifier controller

ESP8266 MQTT Sharp-fu-y30 air purifier controller Disclaimer Note: if you decide to do those changes to your air purifier, you take all the responsibi

xis 2 May 14, 2022
Arduino library for making an IHC in or output module using an Arduino

Introduction This is an Arduino library for making an IHC in or output module using an Arduino. (IHC controller is a home automation controller made b

Jens Østergaard Nielsen 2 Mar 26, 2020
ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT Cloud

ArduinoIoTCloud What? The ArduinoIoTCloud library is the central element of the firmware enabling certain Arduino boards to connect to the Arduino IoT

Arduino Libraries 59 Jun 21, 2022
Arduino support for TinyUSB stack

Adafruit TinyUSB Library for Arduino This library is a Arduino-friendly version of TinyUSB stack. It is designed with structure and APIs that are easi

Adafruit Industries 226 Jun 23, 2022
The Approximate Library is a WiFi Arduino library for building proximate interactions between your Internet of Things and the ESP8266 or ESP32

The Approximate Library The Approximate library is a WiFi Arduino Library for building proximate interactions between your Internet of Things and the

David Chatting 98 Jun 25, 2022
Simple application log library. supporting multiple log levels, custom output & flash memory support.

ArduinoLog - C++ Log library for Arduino devices An minimalistic Logging framework for Arduino-compatible embedded systems. ArduinoLog is a minimalist

Thijs Elenbaas 125 Jun 7, 2022
Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames.

107-Arduino-MCP2515 Arduino library for controlling the MCP2515 in order to receive/transmit CAN frames. This library is prepared to interface easily

107-Systems 45 Jun 19, 2022
Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages.

107-Arduino-NMEA-Parser Arduino library for interfacing with any GPS, GLONASS, Galileo or GNSS module and interpreting its NMEA messages. This library

107-Systems 12 May 16, 2022
Arduino library for providing a convenient C++ interface for accessing UAVCAN.

107-Arduino-UAVCAN Arduino library for providing a convenient C++ interface for accessing UAVCAN (v1.0-beta) utilizing libcanard. This library works f

107-Systems 47 Jun 20, 2022
Arduino web server library.

aWOT Arduino web server library. Documentation 1. Getting started Hello World Basic routing Application generator Serving static files 2. Guide Routin

Lasse Lukkari 234 Jun 12, 2022
Arduino, esp32 and esp8266 library for ABB (ex PowerOne) Aurora Inverter, implement a full methods to retrieve data from the Inverter via RS-485

ABB Aurora protocol You can refer the complete documentation on my site ABB Aurora PV inverter library for Arduino, esp8266 and esp32 I create this li

Renzo Mischianti 20 May 30, 2022
Arduino library for the MCP2515 CAN Controller

MCP2515 CAN Controller Library for Arduino Compatibility with the ACAN library This library is fully compatible with the Teensy 3.x ACAN library https

Pierre Molinaro 3 Oct 1, 2021
CAN / CANFD Arduino Library for Teensy 4.0

CAN Library for Teensy 4.0 / 4.1 It handles Controller Area Network (CAN) for CAN1, CAN2 and CAN3, and Controller Area Network with Flexible Data (CAN

Pierre Molinaro 8 Feb 11, 2022
Analog Devices Analog Digital Converter AD7173 Arduino library

AD7173-Arduino Analog Devices AD7173 analog digital converter Arduino library Mostly tested setup for this library: 1007 data rate external crystal co

brain-duino 8 Jan 13, 2022
Arduino library for nRF51822-based Adafruit Bluefruit LE modules

This library is for all nRF51 based Adafruit Bluefruit LE modules that use SPI or UART. Current nRF51 based Bluefruit LE products include: Bluefruit L

Adafruit Industries 181 Jun 15, 2022
Arduino library for the Adafruit FONA

Adafruit FONA Library This library requires Arduino v1.0.6 or higher This is a library for the Adafruit FONA Cellular GSM Breakouts etc Designed speci

Adafruit Industries 198 Jun 25, 2022
Arduino library to access Adafruit IO from WiFi, cellular, and ethernet modules.

Adafruit IO Arduino Library This library provides a simple device independent interface for interacting with Adafruit IO using Arduino. It allows you

Adafruit Industries 158 Jun 21, 2022