{"id":99498,"date":"2020-11-03T11:33:57","date_gmt":"2020-11-03T11:33:57","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=99498"},"modified":"2020-11-03T11:34:00","modified_gmt":"2020-11-03T11:34:00","slug":"micropython-mqtt-publish-bme680-esp32-esp8266","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/micropython-mqtt-publish-bme680-esp32-esp8266\/","title":{"rendered":"MicroPython: MQTT \u2013 Publish BME680 Sensor Readings (ESP32\/ESP8266)"},"content":{"rendered":"\n<p>Learn how to program the ESP32 or ESP8266 boards with MicroPython to publish BME680 sensor readings (temperature, humidity, pressure, gas\/air quality) via MQTT to any platform that supports MQTT or any MQTT client. As an example, we\u2019ll publish sensor readings to Node-RED Dashboard.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"MicroPython MQTT Publish BME680 Sensor Readings ESP32 ESP8266 temperature humidity pressure air quality gas\" class=\"wp-image-99505\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n\n<p class=\"rntbox rntclgray\"><strong>Recommended reading:<\/strong>&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/what-is-mqtt-and-how-it-works\/\">What is MQTT and How It Works<\/a> <\/p>\n\n\n\n<p><strong>Note: <\/strong> <em>this tutorial&nbsp;is compatible with both the ESP32 and ESP8266&nbsp;development boards.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Overview<\/h2>\n\n\n\n<p>The following diagram shows a high-level overview of the project we&#8217;ll build.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"886\" height=\"632\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-NodeMCU-Overview-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.png?resize=886%2C632&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 NodeMCU Project Overview MQTT Publish BME680 Temperature Humidity Pressure Gas Readings\" class=\"wp-image-99517\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-NodeMCU-Overview-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.png?w=886&amp;quality=100&amp;strip=all&amp;ssl=1 886w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-NodeMCU-Overview-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.png?resize=300%2C214&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-NodeMCU-Overview-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.png?resize=768%2C548&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure><\/div>\n\n\n\n<ul class=\"wp-block-list\"><li>The ESP requests temperature and humidity readings from the BME680 sensor;<\/li><li>Temperature readings are published in the&nbsp;<strong>esp\/bme680\/temperature<\/strong>&nbsp;topic;<\/li><li>Humidity readings are published in the&nbsp;<strong>esp\/bme680\/humidity<\/strong> topic;<\/li><li>Pressure readings are published in the&nbsp;<strong>esp\/bme680\/pressure<\/strong> topic;<\/li><li>Pressure readings are published in the&nbsp;<strong>esp\/bme680\/gas<\/strong> topic;<\/li><li>Node-RED is subscribed to those topics;<\/li><li>Node-RED receives the sensor readings and displays them on gauges;<\/li><li>You can receive the readings in any other platform that supports MQTT and handle the readings as you want.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before continuing with this tutorial, make sure you complete the following prerequisites:<\/p>\n\n\n\n<p>To follow this tutorial you need MicroPython firmware installed in your ESP32 or ESP8266 boards. You also need an IDE to write and upload the code to your board. We suggest using Thonny IDE or uPyCraft IDE:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Thonny IDE:<ul><li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-thonny-micropython-python-ide-esp32-esp8266\/\">Installing and getting started with Thonny IDE<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/flashing-micropython-firmware-esptool-py-esp32-esp8266\/\">Flashing MicroPython Firmware with esptool.py<\/a><\/li><\/ul><\/li><li>uPyCraft IDE:<ul><li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-micropython-esp32-esp8266\/\">Getting Started with uPyCraft IDE<\/a><\/li><li>Install uPyCraft IDE (<a href=\"https:\/\/randomnerdtutorials.com\/install-upycraft-ide-windows-pc-instructions\/\">Windows<\/a>,&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/install-upycraft-ide-mac-os-x-instructions\/\">Mac OS X<\/a>,&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/install-upycraft-ide-linux-ubuntu-instructions\/\">Linux<\/a>)<\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/flash-upload-micropython-firmware-esp32-esp8266\/\">Flash\/Upload MicroPython Firmware to ESP32 and ESP8266<\/a><\/li><\/ul><\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">MQTT Broker<\/h3>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"200\" height=\"197\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/01\/mosquitto-broker.png?resize=200%2C197&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Mosquitto MQTT Broker\" class=\"wp-image-73566\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/01\/mosquitto-broker.png?w=200&amp;quality=100&amp;strip=all&amp;ssl=1 200w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/01\/mosquitto-broker.png?resize=80%2C80&amp;quality=100&amp;strip=all&amp;ssl=1 80w\" sizes=\"(max-width: 200px) 100vw, 200px\" \/><\/figure><\/div>\n\n\n\n<p>To use MQTT, you need a broker. We&#8217;ll be using <a href=\"https:\/\/mosquitto.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Mosquitto broker<\/a> installed on a Raspberry Pi. Read&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/how-to-install-mosquitto-broker-on-raspberry-pi\/\" target=\"_blank\" rel=\"noreferrer noopener\">How to Install Mosquitto Broker on Raspberry Pi<\/a>.<\/p>\n\n\n\n<p>If you&#8217;re not familiar with MQTT make sure you read our introductory tutorial:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/what-is-mqtt-and-how-it-works\/\" target=\"_blank\" rel=\"noreferrer noopener\">What is MQTT and How It Works<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Parts Required<\/h3>\n\n\n\n<p>For this tutorial you need the following parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">ESP32<\/a>&nbsp;(read&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\">Best ESP32 development boards<\/a>) or <a aria-label=\"ESP8266 (opens in a new tab)\" rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/esp8266-esp-12e-nodemcu-wi-fi-development-board\/\" target=\"_blank\">ESP8266<\/a><\/li><li><a href=\"https:\/\/makeradvisor.com\/tools\/bme680-gas-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME680<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/raspberry-pi-board\/\" target=\"_blank\">Raspberry Pi board<\/a>&nbsp;(read&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/best-raspberry-pi-starter-kits\/\" target=\"_blank\">Best Raspberry Pi Starter Kits<\/a>)<\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/microsd-card-raspberry-pi-16gb-class-10\/\" target=\"_blank\">MicroSD Card \u2013 16GB Class10<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-power-supply\/\" target=\"_blank\">Raspberry Pi Power Supply (5V 2.5A)<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\">Jumper wires<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\">Breadboard<\/a><\/li><\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">umqtttsimple Library<\/h2>\n\n\n\n<p>To use MQTT with the ESP32\/ESP8266 and MicroPython, we&#8217;ll use the <em>umqttsimple<\/em>.py library. Follow the next set of instructions for the IDE you&#8217;re using:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>A. Upload umqttsimple library with uPyCraft IDE<\/li><li>B. Upload umqttsimple library with Thonny IDE<\/li><\/ul>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\">try:\n    import usocket as socket\nexcept:\n    import socket\nimport ustruct as struct\nfrom ubinascii import hexlify\n\nclass MQTTException(Exception):\n    pass\n\nclass MQTTClient:\n\n    def __init__(self, client_id, server, port=0, user=None, password=None, keepalive=0,\n                 ssl=False, ssl_params={}):\n        if port == 0:\n            port = 8883 if ssl else 1883\n        self.client_id = client_id\n        self.sock = None\n        self.server = server\n        self.port = port\n        self.ssl = ssl\n        self.ssl_params = ssl_params\n        self.pid = 0\n        self.cb = None\n        self.user = user\n        self.pswd = password\n        self.keepalive = keepalive\n        self.lw_topic = None\n        self.lw_msg = None\n        self.lw_qos = 0\n        self.lw_retain = False\n\n    def _send_str(self, s):\n        self.sock.write(struct.pack(&quot;!H&quot;, len(s)))\n        self.sock.write(s)\n\n    def _recv_len(self):\n        n = 0\n        sh = 0\n        while 1:\n            b = self.sock.read(1)[0]\n            n |= (b &amp; 0x7f) &lt;&lt; sh\n            if not b &amp; 0x80:\n                return n\n            sh += 7\n\n    def set_callback(self, f):\n        self.cb = f\n\n    def set_last_will(self, topic, msg, retain=False, qos=0):\n        assert 0 &lt;= qos &lt;= 2\n        assert topic\n        self.lw_topic = topic\n        self.lw_msg = msg\n        self.lw_qos = qos\n        self.lw_retain = retain\n\n    def connect(self, clean_session=True):\n        self.sock = socket.socket()\n        addr = socket.getaddrinfo(self.server, self.port)[0][-1]\n        self.sock.connect(addr)\n        if self.ssl:\n            import ussl\n            self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)\n        premsg = bytearray(b&quot;\\x10\\0\\0\\0\\0\\0&quot;)\n        msg = bytearray(b&quot;\\x04MQTT\\x04\\x02\\0\\0&quot;)\n\n        sz = 10 + 2 + len(self.client_id)\n        msg[6] = clean_session &lt;&lt; 1\n        if self.user is not None:\n            sz += 2 + len(self.user) + 2 + len(self.pswd)\n            msg[6] |= 0xC0\n        if self.keepalive:\n            assert self.keepalive &lt; 65536\n            msg[7] |= self.keepalive &gt;&gt; 8\n            msg[8] |= self.keepalive &amp; 0x00FF\n        if self.lw_topic:\n            sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)\n            msg[6] |= 0x4 | (self.lw_qos &amp; 0x1) &lt;&lt; 3 | (self.lw_qos &amp; 0x2) &lt;&lt; 3\n            msg[6] |= self.lw_retain &lt;&lt; 5\n\n        i = 1\n        while sz &gt; 0x7f:\n            premsg[i] = (sz &amp; 0x7f) | 0x80\n            sz &gt;&gt;= 7\n            i += 1\n        premsg[i] = sz\n\n        self.sock.write(premsg, i + 2)\n        self.sock.write(msg)\n        #print(hex(len(msg)), hexlify(msg, &quot;:&quot;))\n        self._send_str(self.client_id)\n        if self.lw_topic:\n            self._send_str(self.lw_topic)\n            self._send_str(self.lw_msg)\n        if self.user is not None:\n            self._send_str(self.user)\n            self._send_str(self.pswd)\n        resp = self.sock.read(4)\n        assert resp[0] == 0x20 and resp[1] == 0x02\n        if resp[3] != 0:\n            raise MQTTException(resp[3])\n        return resp[2] &amp; 1\n\n    def disconnect(self):\n        self.sock.write(b&quot;\\xe0\\0&quot;)\n        self.sock.close()\n\n    def ping(self):\n        self.sock.write(b&quot;\\xc0\\0&quot;)\n\n    def publish(self, topic, msg, retain=False, qos=0):\n        pkt = bytearray(b&quot;\\x30\\0\\0\\0&quot;)\n        pkt[0] |= qos &lt;&lt; 1 | retain\n        sz = 2 + len(topic) + len(msg)\n        if qos &gt; 0:\n            sz += 2\n        assert sz &lt; 2097152\n        i = 1\n        while sz &gt; 0x7f:\n            pkt[i] = (sz &amp; 0x7f) | 0x80\n            sz &gt;&gt;= 7\n            i += 1\n        pkt[i] = sz\n        #print(hex(len(pkt)), hexlify(pkt, &quot;:&quot;))\n        self.sock.write(pkt, i + 1)\n        self._send_str(topic)\n        if qos &gt; 0:\n            self.pid += 1\n            pid = self.pid\n            struct.pack_into(&quot;!H&quot;, pkt, 0, pid)\n            self.sock.write(pkt, 2)\n        self.sock.write(msg)\n        if qos == 1:\n            while 1:\n                op = self.wait_msg()\n                if op == 0x40:\n                    sz = self.sock.read(1)\n                    assert sz == b&quot;\\x02&quot;\n                    rcv_pid = self.sock.read(2)\n                    rcv_pid = rcv_pid[0] &lt;&lt; 8 | rcv_pid[1]\n                    if pid == rcv_pid:\n                        return\n        elif qos == 2:\n            assert 0\n\n    def subscribe(self, topic, qos=0):\n        assert self.cb is not None, &quot;Subscribe callback is not set&quot;\n        pkt = bytearray(b&quot;\\x82\\0\\0\\0&quot;)\n        self.pid += 1\n        struct.pack_into(&quot;!BH&quot;, pkt, 1, 2 + 2 + len(topic) + 1, self.pid)\n        #print(hex(len(pkt)), hexlify(pkt, &quot;:&quot;))\n        self.sock.write(pkt)\n        self._send_str(topic)\n        self.sock.write(qos.to_bytes(1, &quot;little&quot;))\n        while 1:\n            op = self.wait_msg()\n            if op == 0x90:\n                resp = self.sock.read(4)\n                #print(resp)\n                assert resp[1] == pkt[2] and resp[2] == pkt[3]\n                if resp[3] == 0x80:\n                    raise MQTTException(resp[3])\n                return\n\n    # Wait for a single incoming MQTT message and process it.\n    # Subscribed messages are delivered to a callback previously\n    # set by .set_callback() method. Other (internal) MQTT\n    # messages processed internally.\n    def wait_msg(self):\n        res = self.sock.read(1)\n        self.sock.setblocking(True)\n        if res is None:\n            return None\n        if res == b&quot;&quot;:\n            raise OSError(-1)\n        if res == b&quot;\\xd0&quot;:  # PINGRESP\n            sz = self.sock.read(1)[0]\n            assert sz == 0\n            return None\n        op = res[0]\n        if op &amp; 0xf0 != 0x30:\n            return op\n        sz = self._recv_len()\n        topic_len = self.sock.read(2)\n        topic_len = (topic_len[0] &lt;&lt; 8) | topic_len[1]\n        topic = self.sock.read(topic_len)\n        sz -= topic_len + 2\n        if op &amp; 6:\n            pid = self.sock.read(2)\n            pid = pid[0] &lt;&lt; 8 | pid[1]\n            sz -= 2\n        msg = self.sock.read(sz)\n        self.cb(topic, msg)\n        if op &amp; 6 == 2:\n            pkt = bytearray(b&quot;\\x40\\x02\\0\\0&quot;)\n            struct.pack_into(&quot;!H&quot;, pkt, 2, pid)\n            self.sock.write(pkt)\n        elif op &amp; 6 == 4:\n            assert 0\n\n    # Checks whether a pending message from server is available.\n    # If not, returns immediately with None. Otherwise, does\n    # the same processing as wait_msg.\n    def check_msg(self):\n        self.sock.setblocking(False)\n        return self.wait_msg()\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP-MicroPython\/raw\/master\/code\/MQTT\/umqttsimple.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A. Upload umqttsimple library with uPyCraft IDE<\/h3>\n\n\n\n<p><strong>1.<\/strong> Create a new file by pressing the <strong>New File<\/strong> button.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"135\" height=\"41\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/uPycraft-ide-tools-menu-new-file.png?resize=135%2C41&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-75063\"\/><\/figure><\/div>\n\n\n\n<p><strong>2.<\/strong> Copy the <em>umqttsimple<\/em> library code into it. You can access the <em>umqttsimple<\/em> library code in the following link:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP-MicroPython\/master\/code\/MQTT\/umqttsimple.py\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP-MicroPython\/master\/code\/MQTT\/umqttsimple.py<\/a><\/li><\/ul>\n\n\n\n<p><strong>3.<\/strong> Save the file by pressing the <strong>Save<\/strong> button.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"142\" height=\"47\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/uPycraft-ide-tools-menu-save-file.png?resize=142%2C47&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-75064\"\/><\/figure><\/div>\n\n\n\n<p><strong>4.<\/strong> Call this new file \u201c<strong>umqttsimple.py<\/strong>\u201d and press <strong>ok<\/strong>.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"305\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/import-umqttsimple-library.png?resize=750%2C305&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"save new umqttsimple.py upycraft IDE\" class=\"wp-image-78499\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/import-umqttsimple-library.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/import-umqttsimple-library.png?resize=300%2C122&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p><strong>5.<\/strong> Click the <strong>Download and Run<\/strong> button.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"238\" height=\"45\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/uPycraft-ide-tools-menu-download-and-run.png?resize=238%2C45&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-75060\"\/><\/figure><\/div>\n\n\n\n<p><strong>6.<\/strong> The file should be saved on the <em>device<\/em> folder with the name \u201c<strong>umqttsimple.py<\/strong>\u201d as highlighted in the figure below.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"468\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/umqttsimple-library-installed.png?resize=750%2C468&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"save umqttsimple.py upycraft IDE\" class=\"wp-image-78502\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/umqttsimple-library-installed.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/12\/umqttsimple-library-installed.png?resize=300%2C187&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n\n<p>Now, you can use the library functionalities in your code by importing the library.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">B. Upload umqttsimple library with Thonny IDE<\/h3>\n\n\n\n<p><strong>1.<\/strong> Copy the library code to a new file. The <a aria-label=\"umqttsimple library code can be found here (opens in a new tab)\" rel=\"noreferrer noopener\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/ESP-MicroPython\/master\/code\/MQTT\/umqttsimple.py\" target=\"_blank\">umqttsimple library code can be found here<\/a>.<\/p>\n\n\n\n<p><strong>2.<\/strong> Go to <strong>File<\/strong> &gt; <strong>Save as&#8230;<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"206\" height=\"294\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/Thonny-IDE-ESP32-ESP8266-MicroPython-Save-file-library-to-device-save-as.png?resize=206%2C294&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Thonny IDE ESP32 ESP8266 MicroPython Save file library to device save as\" class=\"wp-image-99603\"\/><\/figure><\/div>\n\n\n\n<p><strong>3.<\/strong> Select save to &#8220;<strong>MicroPython device<\/strong>&#8220;:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"220\" height=\"202\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/Thonny-IDE-ESP32-ESP8266-MicroPython-Save-file-library-to-device-select.png?resize=220%2C202&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Thonny IDE ESP32 ESP8266 MicroPython Save file library to device select\" class=\"wp-image-99605\"\/><\/figure><\/div>\n\n\n\n<p><strong>4.<\/strong> Name your file as <em>umqttsimple.py<\/em> and press the OK button:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"263\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-new-MicroPython-file-Thonny-IDE.png?resize=553%2C263&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"umqttsimple library new MicroPython file Thonny IDE\" class=\"wp-image-99632\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-new-MicroPython-file-Thonny-IDE.png?w=553&amp;quality=100&amp;strip=all&amp;ssl=1 553w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-new-MicroPython-file-Thonny-IDE.png?resize=300%2C143&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 553px) 100vw, 553px\" \/><\/figure><\/div>\n\n\n\n<p>And that&#8217;s it. The library was uploaded to your board. To make sure that it was uploaded successfully, go to File &gt; Save as&#8230; and select the MicroPython device. Your file should be listed there:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"553\" height=\"289\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-MicroPython-file-created-Thonny-IDE.png?resize=553%2C289&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"umqttsimple library MicroPython file created Thonny IDE\" class=\"wp-image-99631\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-MicroPython-file-created-Thonny-IDE.png?w=553&amp;quality=100&amp;strip=all&amp;ssl=1 553w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/umqttsimple-library-MicroPython-file-created-Thonny-IDE.png?resize=300%2C157&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 553px) 100vw, 553px\" \/><\/figure><\/div>\n\n\n\n<p>After uploading the library to your board, you can use the library functionalities in your code by importing the library.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">BME680 MicroPython Library<\/h2>\n\n\n\n<p>The library to read from the BME680 sensor isn\u2019t part of the standard MicroPython library by default. So, you need to upload the following library to your ESP32\/ESP8266 board (save it with the name <em>bme680.py<\/em>).<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Spaces, comments and some functions have been removed from the original file to save memory\n# Original source: https:\/\/github.com\/adafruit\/Adafruit_CircuitPython_BME680\/blob\/master\/adafruit_bme680.py\nimport time\nimport math\nfrom micropython import const\nfrom ubinascii import hexlify as hex\ntry:\n  import struct\nexcept ImportError:\n  import ustruct as struct\n_BME680_CHIPID = const(0x61)\n_BME680_REG_CHIPID = const(0xD0)\n_BME680_BME680_COEFF_ADDR1 = const(0x89)\n_BME680_BME680_COEFF_ADDR2 = const(0xE1)\n_BME680_BME680_RES_HEAT_0 = const(0x5A)\n_BME680_BME680_GAS_WAIT_0 = const(0x64)\n_BME680_REG_SOFTRESET = const(0xE0)\n_BME680_REG_CTRL_GAS = const(0x71)\n_BME680_REG_CTRL_HUM = const(0x72)\n_BME280_REG_STATUS = const(0xF3)\n_BME680_REG_CTRL_MEAS = const(0x74)\n_BME680_REG_CONFIG = const(0x75)\n_BME680_REG_PAGE_SELECT = const(0x73)\n_BME680_REG_MEAS_STATUS = const(0x1D)\n_BME680_REG_PDATA = const(0x1F)\n_BME680_REG_TDATA = const(0x22)\n_BME680_REG_HDATA = const(0x25)\n_BME680_SAMPLERATES = (0, 1, 2, 4, 8, 16)\n_BME680_FILTERSIZES = (0, 1, 3, 7, 15, 31, 63, 127)\n_BME680_RUNGAS = const(0x10)\n_LOOKUP_TABLE_1 = (2147483647.0, 2147483647.0, 2147483647.0, 2147483647.0, 2147483647.0,\n  2126008810.0, 2147483647.0, 2130303777.0, 2147483647.0, 2147483647.0,\n  2143188679.0, 2136746228.0, 2147483647.0, 2126008810.0, 2147483647.0,\n  2147483647.0)\n_LOOKUP_TABLE_2 = (4096000000.0, 2048000000.0, 1024000000.0, 512000000.0, 255744255.0, 127110228.0,\n  64000000.0, 32258064.0, 16016016.0, 8000000.0, 4000000.0, 2000000.0, 1000000.0,\n  500000.0, 250000.0, 125000.0)\ndef _read24(arr):\n  ret = 0.0\n  for b in arr:\n    ret *= 256.0\n    ret += float(b &amp; 0xFF)\n  return ret\nclass Adafruit_BME680:\n  def __init__(self, *, refresh_rate=10):\n    self._write(_BME680_REG_SOFTRESET, [0xB6])\n    time.sleep(0.005)\n    chip_id = self._read_byte(_BME680_REG_CHIPID)\n    if chip_id != _BME680_CHIPID:\n      raise RuntimeError('Failed 0x%x' % chip_id)\n    self._read_calibration()\n    self._write(_BME680_BME680_RES_HEAT_0, [0x73])\n    self._write(_BME680_BME680_GAS_WAIT_0, [0x65])\n    self.sea_level_pressure = 1013.25\n    self._pressure_oversample = 0b011\n    self._temp_oversample = 0b100\n    self._humidity_oversample = 0b010\n    self._filter = 0b010\n    self._adc_pres = None\n    self._adc_temp = None\n    self._adc_hum = None\n    self._adc_gas = None\n    self._gas_range = None\n    self._t_fine = None\n    self._last_reading = 0\n    self._min_refresh_time = 1000 \/ refresh_rate\n  @property\n  def pressure_oversample(self):\n    return _BME680_SAMPLERATES[self._pressure_oversample]\n  @pressure_oversample.setter\n  def pressure_oversample(self, sample_rate):\n    if sample_rate in _BME680_SAMPLERATES:\n      self._pressure_oversample = _BME680_SAMPLERATES.index(sample_rate)\n    else:\n      raise RuntimeError(&quot;Invalid&quot;)\n  @property\n  def humidity_oversample(self):\n    return _BME680_SAMPLERATES[self._humidity_oversample]\n  @humidity_oversample.setter\n  def humidity_oversample(self, sample_rate):\n    if sample_rate in _BME680_SAMPLERATES:\n      self._humidity_oversample = _BME680_SAMPLERATES.index(sample_rate)\n    else:\n      raise RuntimeError(&quot;Invalid&quot;)\n  @property\n  def temperature_oversample(self):\n      return _BME680_SAMPLERATES[self._temp_oversample]\n  @temperature_oversample.setter\n  def temperature_oversample(self, sample_rate):\n    if sample_rate in _BME680_SAMPLERATES:\n      self._temp_oversample = _BME680_SAMPLERATES.index(sample_rate)\n    else:\n      raise RuntimeError(&quot;Invalid&quot;)\n  @property\n  def filter_size(self):\n    return _BME680_FILTERSIZES[self._filter]\n  @filter_size.setter\n  def filter_size(self, size):\n    if size in _BME680_FILTERSIZES:\n      self._filter = _BME680_FILTERSIZES[size]\n    else:\n      raise RuntimeError(&quot;Invalid&quot;)\n  @property\n  def temperature(self):\n    self._perform_reading()\n    calc_temp = (((self._t_fine * 5) + 128) \/ 256)\n    return calc_temp \/ 100\n  @property\n  def pressure(self):\n    self._perform_reading()\n    var1 = (self._t_fine \/ 2) - 64000\n    var2 = ((var1 \/ 4) * (var1 \/ 4)) \/ 2048\n    var2 = (var2 * self._pressure_calibration[5]) \/ 4\n    var2 = var2 + (var1 * self._pressure_calibration[4] * 2)\n    var2 = (var2 \/ 4) + (self._pressure_calibration[3] * 65536)\n    var1 = (((((var1 \/ 4) * (var1 \/ 4)) \/ 8192) *\n      (self._pressure_calibration[2] * 32) \/ 8) +\n      ((self._pressure_calibration[1] * var1) \/ 2))\n    var1 = var1 \/ 262144\n    var1 = ((32768 + var1) * self._pressure_calibration[0]) \/ 32768\n    calc_pres = 1048576 - self._adc_pres\n    calc_pres = (calc_pres - (var2 \/ 4096)) * 3125\n    calc_pres = (calc_pres \/ var1) * 2\n    var1 = (self._pressure_calibration[8] * (((calc_pres \/ 8) * (calc_pres \/ 8)) \/ 8192)) \/ 4096\n    var2 = ((calc_pres \/ 4) * self._pressure_calibration[7]) \/ 8192\n    var3 = (((calc_pres \/ 256) ** 3) * self._pressure_calibration[9]) \/ 131072\n    calc_pres += ((var1 + var2 + var3 + (self._pressure_calibration[6] * 128)) \/ 16)\n    return calc_pres\/100\n  @property\n  def humidity(self):\n    self._perform_reading()\n    temp_scaled = ((self._t_fine * 5) + 128) \/ 256\n    var1 = ((self._adc_hum - (self._humidity_calibration[0] * 16)) -\n      ((temp_scaled * self._humidity_calibration[2]) \/ 200))\n    var2 = (self._humidity_calibration[1] *\n      (((temp_scaled * self._humidity_calibration[3]) \/ 100) +\n       (((temp_scaled * ((temp_scaled * self._humidity_calibration[4]) \/ 100)) \/\n         64) \/ 100) + 16384)) \/ 1024\n    var3 = var1 * var2\n    var4 = self._humidity_calibration[5] * 128\n    var4 = (var4 + ((temp_scaled * self._humidity_calibration[6]) \/ 100)) \/ 16\n    var5 = ((var3 \/ 16384) * (var3 \/ 16384)) \/ 1024\n    var6 = (var4 * var5) \/ 2\n    calc_hum = (((var3 + var6) \/ 1024) * 1000) \/ 4096\n    calc_hum \/= 1000\n    if calc_hum &gt; 100:\n      calc_hum = 100\n    if calc_hum &lt; 0:\n      calc_hum = 0\n    return calc_hum\n  @property\n  def altitude(self):\n    pressure = self.pressure\n    return 44330 * (1.0 - math.pow(pressure \/ self.sea_level_pressure, 0.1903))\n  @property\n  def gas(self):\n    self._perform_reading()\n    var1 = ((1340 + (5 * self._sw_err)) * (_LOOKUP_TABLE_1[self._gas_range])) \/ 65536\n    var2 = ((self._adc_gas * 32768) - 16777216) + var1\n    var3 = (_LOOKUP_TABLE_2[self._gas_range] * var1) \/ 512\n    calc_gas_res = (var3 + (var2 \/ 2)) \/ var2\n    return int(calc_gas_res)\n  def _perform_reading(self):\n    if (time.ticks_diff(self._last_reading, time.ticks_ms()) * time.ticks_diff(0, 1)\n        &lt; self._min_refresh_time):\n      return\n    self._write(_BME680_REG_CONFIG, [self._filter &lt;&lt; 2])\n    self._write(_BME680_REG_CTRL_MEAS,\n      [(self._temp_oversample &lt;&lt; 5)|(self._pressure_oversample &lt;&lt; 2)])\n    self._write(_BME680_REG_CTRL_HUM, [self._humidity_oversample])\n    self._write(_BME680_REG_CTRL_GAS, [_BME680_RUNGAS])\n    ctrl = self._read_byte(_BME680_REG_CTRL_MEAS)\n    ctrl = (ctrl &amp; 0xFC) | 0x01\n    self._write(_BME680_REG_CTRL_MEAS, [ctrl])\n    new_data = False\n    while not new_data:\n      data = self._read(_BME680_REG_MEAS_STATUS, 15)\n      new_data = data[0] &amp; 0x80 != 0\n      time.sleep(0.005)\n    self._last_reading = time.ticks_ms()\n    self._adc_pres = _read24(data[2:5]) \/ 16\n    self._adc_temp = _read24(data[5:8]) \/ 16\n    self._adc_hum = struct.unpack('&gt;H', bytes(data[8:10]))[0]\n    self._adc_gas = int(struct.unpack('&gt;H', bytes(data[13:15]))[0] \/ 64)\n    self._gas_range = data[14] &amp; 0x0F\n    var1 = (self._adc_temp \/ 8) - (self._temp_calibration[0] * 2)\n    var2 = (var1 * self._temp_calibration[1]) \/ 2048\n    var3 = ((var1 \/ 2) * (var1 \/ 2)) \/ 4096\n    var3 = (var3 * self._temp_calibration[2] * 16) \/ 16384\n    self._t_fine = int(var2 + var3)\n  def _read_calibration(self):\n    coeff = self._read(_BME680_BME680_COEFF_ADDR1, 25)\n    coeff += self._read(_BME680_BME680_COEFF_ADDR2, 16)\n    coeff = list(struct.unpack('&lt;hbBHhbBhhbbHhhBBBHbbbBbHhbb', bytes(coeff[1:39])))\n    coeff = [float(i) for i in coeff]\n    self._temp_calibration = [coeff[x] for x in [23, 0, 1]]\n    self._pressure_calibration = [coeff[x] for x in [3, 4, 5, 7, 8, 10, 9, 12, 13, 14]]\n    self._humidity_calibration = [coeff[x] for x in [17, 16, 18, 19, 20, 21, 22]]\n    self._gas_calibration = [coeff[x] for x in [25, 24, 26]]\n    self._humidity_calibration[1] *= 16\n    self._humidity_calibration[1] += self._humidity_calibration[0] % 16\n    self._humidity_calibration[0] \/= 16\n    self._heat_range = (self._read_byte(0x02) &amp; 0x30) \/ 16\n    self._heat_val = self._read_byte(0x00)\n    self._sw_err = (self._read_byte(0x04) &amp; 0xF0) \/ 16\n  def _read_byte(self, register):\n    return self._read(register, 1)[0]\n  def _read(self, register, length):\n    raise NotImplementedError()\n  def _write(self, register, values):\n    raise NotImplementedError()\nclass BME680_I2C(Adafruit_BME680):\n  def __init__(self, i2c, address=0x77, debug=False, *, refresh_rate=10):\n    self._i2c = i2c\n    self._address = address\n    self._debug = debug\n    super().__init__(refresh_rate=refresh_rate)\n  def _read(self, register, length):\n    result = bytearray(length)\n    self._i2c.readfrom_mem_into(self._address, register &amp; 0xff, result)\n    if self._debug:\n      print(&quot;\\t${:x} read &quot;.format(register), &quot; &quot;.join([&quot;{:02x}&quot;.format(i) for i in result]))\n    return result\n  def _write(self, register, values):\n    if self._debug:\n      print(&quot;\\t${:x} write&quot;.format(register), &quot; &quot;.join([&quot;{:02x}&quot;.format(i) for i in values]))\n    for value in values:\n      self._i2c.writeto_mem(self._address, register, bytearray([value &amp; 0xFF]))\n      register += 1\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP-MicroPython\/bme680.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schematic: ESP32 with BME680<\/h2>\n\n\n\n<p>Wire the <a href=\"https:\/\/makeradvisor.com\/tools\/bme680-gas-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME680 sensor<\/a> to the ESP32 development board as shown in the following schematic diagram. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"669\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32_BME680_Wiring_Diagram_I2C.png?resize=786%2C669&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 BME680 Wiring Diagram I2C\" class=\"wp-image-98165\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32_BME680_Wiring_Diagram_I2C.png?w=786&amp;quality=100&amp;strip=all&amp;ssl=1 786w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32_BME680_Wiring_Diagram_I2C.png?resize=300%2C255&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP32_BME680_Wiring_Diagram_I2C.png?resize=768%2C654&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/figure><\/div>\n\n\n\n<p class=\"rntbox rntclgray\">Learn how to use the ESP32 GPIOs with our guide:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp32-pinout-reference-gpios\/\">ESP32 Pinout Reference: Which GPIO pins should you use?<\/a> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Schematic: ESP8266 NodeMCU with BME680<\/h2>\n\n\n\n<p>If you&#8217;re using an ESP8266 NodeMCU, follow the next diagram instead.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"831\" height=\"531\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-BME680-Environmental-Sensor-Wiring-Diagram-I2C-1.png?resize=831%2C531&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP8266 NodeMCU BME680 Environmental Sensor Wiring Diagram I2C\" class=\"wp-image-98397\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-BME680-Environmental-Sensor-Wiring-Diagram-I2C-1.png?w=831&amp;quality=100&amp;strip=all&amp;ssl=1 831w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-BME680-Environmental-Sensor-Wiring-Diagram-I2C-1.png?resize=300%2C192&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-BME680-Environmental-Sensor-Wiring-Diagram-I2C-1.png?resize=768%2C491&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 831px) 100vw, 831px\" \/><\/figure><\/div>\n\n\n\n<p class=\"rntbox rntclgray\">Learn how to use the ESP8266 GPIOs with our guide:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/esp8266-pinout-reference-gpios\/\">ESP8266 Pinout Reference: Which GPIO pins should you use?<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code<\/h2>\n\n\n\n<p>After uploading the libraries to the ESP32 or ESP8266, copy the following code to the <em>main.py<\/em> file. It publishes the temperature, humidity and pressure on the <strong>esp\/bme680\/temperature<\/strong>, <strong>esp\/bme680\/humidity<\/strong>, <strong>esp\/bme680\/pressure<\/strong>, and <strong>esp\/bme680\/gas<\/strong> topics every 5 seconds.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Complete project details at https:\/\/RandomNerdTutorials.com\/micropython-mqtt-publish-bme680-esp32-esp8266\/\n\nimport time\nfrom umqttsimple import MQTTClient\nimport ubinascii\nimport machine\nimport micropython\nimport network\nimport esp\nfrom bme680 import *\nfrom machine import Pin, I2C\n\nesp.osdebug(None)\nimport gc\ngc.collect()\n\nssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'\nmqtt_server = 'XXX.XXX.XXX.XXX'\n#EXAMPLE IP ADDRESS\n#mqtt_server = '192.168.1.106'\n\nclient_id = ubinascii.hexlify(machine.unique_id())\n\ntopic_pub_temp = b'esp\/bme680\/temperature'\ntopic_pub_hum = b'esp\/bme680\/humidity'\ntopic_pub_pres = b'esp\/bme680\/pressure'\ntopic_pub_gas = b'esp\/bme680\/gas'\n\nlast_message = 0\nmessage_interval = 5\n\nstation = network.WLAN(network.STA_IF)\n\nstation.active(True)\nstation.connect(ssid, password)\n\nwhile station.isconnected() == False:\n  pass\n\nprint('Connection successful')\n\n# ESP32 - Pin assignment\n#i2c = I2C(scl=Pin(22), sda=Pin(21))\n# ESP8266 - Pin assignment\ni2c = I2C(scl=Pin(5), sda=Pin(4))\n\nbme = BME680_I2C(i2c=i2c)\n\ndef connect_mqtt():\n  global client_id, mqtt_server\n  client = MQTTClient(client_id, mqtt_server)\n  #client = MQTTClient(client_id, mqtt_server, user=your_username, password=your_password)\n  client.connect()\n  print('Connected to %s MQTT broker' % (mqtt_server))\n  return client\n\ndef restart_and_reconnect():\n  print('Failed to connect to MQTT broker. Reconnecting...')\n  time.sleep(10)\n  machine.reset()\n\ndef read_bme_sensor():\n  try:\n    temp = (b'{:.2f}'.format(bme.temperature))\n    #temp = (b'{0:.2f}'.format((bme.temperature) * (9\/5) + 32))\n    hum = (b'{:.2f}'.format(bme.humidity))\n    pres = (b'{:.2f}'.format(bme.pressure))\n    gas = (b'{:.2f}'.format(bme.gas\/1000))\n    \n    return temp, hum, pres, gas\n    #else:\n    #  return('Invalid sensor readings.')\n  except OSError as e:\n    return('Failed to read sensor.')\n\ntry:\n  client = connect_mqtt()\nexcept OSError as e:\n  restart_and_reconnect()\n\nwhile True:\n  try:\n    if (time.time() - last_message) &gt; message_interval:\n      temp, hum, pres, gas = read_bme_sensor()\n      print(temp)\n      print(hum)\n      print(pres)\n      print(gas)\n      client.publish(topic_pub_temp, temp)\n      client.publish(topic_pub_hum, hum)      \n      client.publish(topic_pub_pres, pres)\n      client.publish(topic_pub_gas, gas)\n      \n      last_message = time.time()\n  except OSError as e:\n    restart_and_reconnect()\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP-MicroPython\/MQTT\/esp_bme680_mqtt.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>Import the following libraries:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import time\nfrom umqttsimple import MQTTClient\nimport ubinascii\nimport machine\nimport micropython\nimport network\nimport esp\nfrom bme680 import *\nfrom machine import Pin, I2C<\/code><\/pre>\n\n\n\n<p>In the following variables, you need to enter your network credentials and your broker IP address.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>ssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'\nmqtt_server = 'REPLACE_WITH_YOUR_MQTT_BROKER_IP'<\/code><\/pre>\n\n\n\n<p>For example, our broker IP address is: 192.168.1.106.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>mqtt_server = '192.168.1.106'<\/code><\/pre>\n\n\n\n<p><strong>Note:<\/strong>&nbsp;read&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/how-to-install-mosquitto-broker-on-raspberry-pi\/\" target=\"_blank\" rel=\"noreferrer noopener\">this tutorial<\/a>&nbsp;to see how to get your broker IP address.<\/p>\n\n\n\n<p>To create an MQTT client, we need to get the ESP unique ID. That\u2019s what we do in the following line (it is saved on the <span class=\"rnthl rntliteral\">client_id<\/span> variable).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>client_id = ubinascii.hexlify(machine.unique_id())<\/code><\/pre>\n\n\n\n<p>Next, create the topics you want your ESP to be publishing in. In our example, it will publish temperature on the <strong>esp\/bme680\/temperature<\/strong> topic, humidity on the <strong>esp\/bme680\/humidity<\/strong> topic, pressure on the <strong>esp\/bme680\/pressure<\/strong> topic, and gas on the <strong>esp\/bme680\/gas<\/strong> topic .<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>topic_pub_temp = b'esp\/bme680\/temperature'\ntopic_pub_hum = b'esp\/bme680\/humidity'\ntopic_pub_pres = b'esp\/bme680\/pressure'\ntopic_pub_gas = b'esp\/bme680\/gas'<\/code><\/pre>\n\n\n\n<p>Then, create the following variables:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>last_message = 0\nmessage_interval = 5<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">last_message<\/span> variable will hold the last time a message was sent. The <span class=\"rnthl rntliteral\">message_interval<\/span> is the time between each message sent. Here, we\u2019re setting it to 5 seconds (this means a new message will be sent every 5 seconds). You can change it, if you want. <\/p>\n\n\n\n<p>After that, connect the ESP to your local network.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>station = network.WLAN(network.STA_IF)\n\nstation.active(True)\nstation.connect(ssid, password)\n\nwhile station.isconnected() == False:\n  pass\n\nprint('Connection successful')<\/code><\/pre>\n\n\n\n<p>Create an <span class=\"rnthl rntliteral\">i2c<\/span> instance on the ESP32 I2C pins to communicate with the BME680 sensor:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>i2c = I2C(scl=Pin(22), sda=Pin(21))<\/code><\/pre>\n\n\n\n<p>If you&#8217;re using an ESP8266, use the following line instead (to use the ESP8266 default I2C pins).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>i2c = I2C(scl=Pin(5), sda=Pin(4))<\/code><\/pre>\n\n\n\n<p>Create a BME680 instance on the ESP I2C pins:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>bme = BME680_I2C(i2c=i2c)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Connect to MQTT Broker<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">connect_mqtt()<\/span> function creates an MQTT Client and connects to your broker.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def connect_mqtt():\n  global client_id, mqtt_server\n  client = MQTTClient(client_id, mqtt_server)\n  #client = MQTTClient(client_id, mqtt_server, user=your_username, password=your_password)\n  client.connect()\n  print('Connected to %s MQTT broker' % (mqtt_server))\n  return client<\/code><\/pre>\n\n\n\n<p>If your MQTT broker requires username and password, you should use the following line to pass your broker username and password as arguments.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>client = MQTTClient(client_id, mqtt_server, user=your_username, password=your_password)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Restart and Reconnect<\/h3>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">restart_and_reconnect()<\/span> function resets the ESP32\/ESP8266 board. This function will be called if we&#8217;re not able to publish the readings via MQTT in case the broker disconnects.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def restart_and_reconnect():\n  print('Failed to connect to MQTT broker. Reconnecting...')\n  time.sleep(10)\n  machine.reset()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Read BME680 Sensor<\/h3>\n\n\n\n<p>We created a function called <span class=\"rnthl rntliteral\">read_bme_sensor()<\/span> that returns the current temperature, humidity and pressure readings from the BME680 sensor and handles any exceptions, in case we&#8217;re not able to get readings from the sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def read_bme_sensor():\n  try:\n    temp = (b'{:.2f}'.format(bme.temperature))\n    #temp = (b'{0:.2f}'.format((bme.temperature) * (9\/5) + 32))\n    hum = (b'{:.2f}'.format(bme.humidity))\n    pres = (b'{:.2f}'.format(bme.pressure))\n    gas = (b'{:.2f}'.format(bme.gas\/1000))\n    \n    return temp, hum, pres, gas\n    #else:\n    #  return('Invalid sensor readings.')\n  except OSError as e:\n    return('Failed to read sensor.')<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Publishing MQTT Messages<\/h3>\n\n\n\n<p>In the while loop, we publish new BME680 readings every 5 seconds.<\/p>\n\n\n\n<p>First, we check if it is time to get new readings:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>if (time.time() - last_message) > message_interval:<\/code><\/pre>\n\n\n\n<p>If it is, request new readings from the BME680 sensor by calling the <span class=\"rnthl rntliteral\">read_bme_sensor()<\/span> function. The temperature is saved on the <span class=\"rnthl rntliteral\">temp<\/span> variable, the humidity is saved on the <span class=\"rnthl rntliteral\">hum<\/span> variable and the pressure on the <span class=\"rnthl rntliteral\">pres<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>temp, hum, pres, gas = read_bme_sensor()<\/code><\/pre>\n\n\n\n<p>Finally, publish the readings by using the <span class=\"rnthl rntliteral\">publish()<\/span> method on the <span class=\"rnthl rntliteral\">client<\/span> object. The <span class=\"rnthl rntliteral\">publish()<\/span> method accepts as arguments the topic and the message, as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>client.publish(topic_pub_temp, temp)\nclient.publish(topic_pub_hum, hum)\nclient.publish(topic_pub_pres, pres)\nclient.publish(topic_pub_gas, gas)<\/code><\/pre>\n\n\n\n<p>Finally, update the time when the last message was sent:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>last_message = time.time()<\/code><\/pre>\n\n\n\n<p>In case the ESP32 or ESP8266 disconnects from the broker, and we&#8217;re not able to publish the readings, call the <span class=\"rnthl rntliteral\">restart_and_reconnect()<\/span> function to reset the ESP board and try to reconnect to the broker.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>except OSError as e:\n  restart_and_reconnect()<\/code><\/pre>\n\n\n\n<p>After uploading the code, you should get new sensor readings on the shell every 5 seconds.<\/p>\n\n\n\n<p>Now, go to the next section to prepare Node-RED to receive the readings the ESP is publishing.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Preparing Node-RED Dashboard<\/h2>\n\n\n\n<p>The ESP32 or ESP8266 is publishing temperature readings every 10 seconds on the <strong>esp\/bme680\/temperature<\/strong>, <strong>esp\/bme680\/humidity<\/strong>, <strong>esp\/bme680\/pressure<\/strong> and <strong>esp\/bme680\/gas<\/strong> topics. Now, you can use any dashboard that supports MQTT or any other device that supports MQTT to subscribe to those topics and receive the readings.<\/p>\n\n\n\n<p>As an example, we&#8217;ll create a simple flow using Node-RED to subscribe to those topics and display the readings on gauges.<\/p>\n\n\n\n<p>If you don&#8217;t have Node-RED installed, follow the next tutorials:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-with-node-red-on-raspberry-pi\/\">Getting Started with Node-RED on Raspberry Pi<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-with-node-red-dashboard\/\">Installing and Getting Started with Node-RED Dashboard<\/a><\/li><\/ul>\n\n\n\n<p>Having Node-RED running on your Raspberry Pi, go to your Raspberry Pi IP address followed by :1880.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;raspberry-pi-ip-address:1880<\/code><\/pre>\n\n\n\n<p>The Node-RED interface should open. Drag four MQTT in nodes, two gauge nodes, and two text fields to the flow.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"246\" height=\"223\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/drag-nodes-esp32-esp8266-node-red-bme680.png?resize=246%2C223&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Drag nodes ESP32 ESP8266 Node-RED BME680\" class=\"wp-image-99513\"\/><\/figure><\/div>\n\n\n\n<p>Click the MQTT node and edit its properties.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"498\" height=\"365\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-mqtt-in-node-esp32-esp8266-node-red-bme680.png?resize=498%2C365&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Edit mqtt in node ESP32 ESP8266 Node-RED BME680\" class=\"wp-image-99515\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-mqtt-in-node-esp32-esp8266-node-red-bme680.png?w=498&amp;quality=100&amp;strip=all&amp;ssl=1 498w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-mqtt-in-node-esp32-esp8266-node-red-bme680.png?resize=300%2C220&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 498px) 100vw, 498px\" \/><\/figure><\/div>\n\n\n\n<p>The Server field refers to the MQTT broker. In our case, the MQTT broker is the Raspberry Pi, so it is set to localhost:1883. If you&#8217;re using a Cloud MQTT broker, you should change that field. <\/p>\n\n\n\n<p>Insert the topic you want to be subscribed to and the QoS. This previous MQTT node is subscribed to the <strong>esp\/bme680\/temperature<\/strong> topic. <\/p>\n\n\n\n<p>Click on the other MQTT in nodes and edit its properties with the same server, but for the other topics: <strong>esp\/bme680\/humidity<\/strong>, <strong>esp\/bme680\/pressure<\/strong>, and <strong>esp\/bme680\/gas<\/strong>.<\/p>\n\n\n\n<p>Click on the gauge nodes and edit its properties for each reading. The following node is set for the temperature readings. Edit the other chart node for the humidity readings.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"499\" height=\"567\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-gauge-node-esp32-esp8266-node-red-bme680.png?resize=499%2C567&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Edit gauge node ESP32 ESP8266 Node-RED BME680\" class=\"wp-image-99514\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-gauge-node-esp32-esp8266-node-red-bme680.png?w=499&amp;quality=100&amp;strip=all&amp;ssl=1 499w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/edit-gauge-node-esp32-esp8266-node-red-bme680.png?resize=264%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 264w\" sizes=\"(max-width: 499px) 100vw, 499px\" \/><\/figure><\/div>\n\n\n\n<p>Wire your nodes as shown below:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"408\" height=\"233\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/node-connected-esp32-esp8266-node-red-bme680.png?resize=408%2C233&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Node connected ESP32 ESP8266 Node-RED BME680\" class=\"wp-image-99512\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/node-connected-esp32-esp8266-node-red-bme680.png?w=408&amp;quality=100&amp;strip=all&amp;ssl=1 408w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/node-connected-esp32-esp8266-node-red-bme680.png?resize=300%2C171&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 408px) 100vw, 408px\" \/><\/figure><\/div>\n\n\n\n<p>Finally, deploy your flow (press the button on the upper right corner).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"138\" height=\"40\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/06\/11_deploy_button.png?resize=138%2C40&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Deploy Node-RED button\" class=\"wp-image-40013\"\/><\/figure><\/div>\n\n\n\n<p>Alternatively, you can go to <strong>Menu <\/strong>&gt; <strong>Import <\/strong>and copy the following to your <strong>Clipboard<\/strong> to create your Node-RED flow.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">[{&quot;id&quot;:&quot;3b7f947c.9759ec&quot;,&quot;type&quot;:&quot;mqtt in&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;topic&quot;:&quot;esp\/bme680\/temperature&quot;,&quot;qos&quot;:&quot;1&quot;,&quot;datatype&quot;:&quot;auto&quot;,&quot;broker&quot;:&quot;8db3fac0.99dd48&quot;,&quot;x&quot;:470,&quot;y&quot;:2640,&quot;wires&quot;:[[&quot;b87b21c3.96672&quot;]]},{&quot;id&quot;:&quot;b87b21c3.96672&quot;,&quot;type&quot;:&quot;ui_gauge&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;group&quot;:&quot;37de8fe8.46846&quot;,&quot;order&quot;:2,&quot;width&quot;:0,&quot;height&quot;:0,&quot;gtype&quot;:&quot;gage&quot;,&quot;title&quot;:&quot;Temperature&quot;,&quot;label&quot;:&quot;\u00baC&quot;,&quot;format&quot;:&quot;{{value}}&quot;,&quot;min&quot;:0,&quot;max&quot;:&quot;40&quot;,&quot;colors&quot;:[&quot;#00b500&quot;,&quot;#f7df09&quot;,&quot;#ca3838&quot;],&quot;seg1&quot;:&quot;&quot;,&quot;seg2&quot;:&quot;&quot;,&quot;x&quot;:690,&quot;y&quot;:2640,&quot;wires&quot;:[]},{&quot;id&quot;:&quot;f92248f4.545778&quot;,&quot;type&quot;:&quot;mqtt in&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;topic&quot;:&quot;esp\/bme680\/humidity&quot;,&quot;qos&quot;:&quot;1&quot;,&quot;datatype&quot;:&quot;auto&quot;,&quot;broker&quot;:&quot;8db3fac0.99dd48&quot;,&quot;x&quot;:460,&quot;y&quot;:2700,&quot;wires&quot;:[[&quot;4114a401.5ac69c&quot;]]},{&quot;id&quot;:&quot;4114a401.5ac69c&quot;,&quot;type&quot;:&quot;ui_gauge&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;group&quot;:&quot;37de8fe8.46846&quot;,&quot;order&quot;:2,&quot;width&quot;:0,&quot;height&quot;:0,&quot;gtype&quot;:&quot;gage&quot;,&quot;title&quot;:&quot;Humidity&quot;,&quot;label&quot;:&quot;%&quot;,&quot;format&quot;:&quot;{{value}}&quot;,&quot;min&quot;:&quot;30&quot;,&quot;max&quot;:&quot;100&quot;,&quot;colors&quot;:[&quot;#53a4e6&quot;,&quot;#1d78a9&quot;,&quot;#4e38c9&quot;],&quot;seg1&quot;:&quot;&quot;,&quot;seg2&quot;:&quot;&quot;,&quot;x&quot;:680,&quot;y&quot;:2700,&quot;wires&quot;:[]},{&quot;id&quot;:&quot;ad51f895.2c2848&quot;,&quot;type&quot;:&quot;mqtt in&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;topic&quot;:&quot;esp\/bme680\/pressure&quot;,&quot;qos&quot;:&quot;1&quot;,&quot;datatype&quot;:&quot;auto&quot;,&quot;broker&quot;:&quot;8db3fac0.99dd48&quot;,&quot;x&quot;:460,&quot;y&quot;:2760,&quot;wires&quot;:[[&quot;3a95123b.66405e&quot;]]},{&quot;id&quot;:&quot;c074e688.198b78&quot;,&quot;type&quot;:&quot;mqtt in&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;name&quot;:&quot;&quot;,&quot;topic&quot;:&quot;esp\/bme680\/gas&quot;,&quot;qos&quot;:&quot;1&quot;,&quot;datatype&quot;:&quot;auto&quot;,&quot;broker&quot;:&quot;8db3fac0.99dd48&quot;,&quot;x&quot;:440,&quot;y&quot;:2820,&quot;wires&quot;:[[&quot;d3539c06.00a17&quot;]]},{&quot;id&quot;:&quot;3a95123b.66405e&quot;,&quot;type&quot;:&quot;ui_text&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;group&quot;:&quot;37de8fe8.46846&quot;,&quot;order&quot;:2,&quot;width&quot;:0,&quot;height&quot;:0,&quot;name&quot;:&quot;&quot;,&quot;label&quot;:&quot;Pressure&quot;,&quot;format&quot;:&quot;{{msg.payload}} hPa&quot;,&quot;layout&quot;:&quot;row-spread&quot;,&quot;x&quot;:680,&quot;y&quot;:2760,&quot;wires&quot;:[]},{&quot;id&quot;:&quot;d3539c06.00a17&quot;,&quot;type&quot;:&quot;ui_text&quot;,&quot;z&quot;:&quot;254c9c97.f85b34&quot;,&quot;group&quot;:&quot;37de8fe8.46846&quot;,&quot;order&quot;:3,&quot;width&quot;:0,&quot;height&quot;:0,&quot;name&quot;:&quot;&quot;,&quot;label&quot;:&quot;Gas&quot;,&quot;format&quot;:&quot;{{msg.payload}} KOhm&quot;,&quot;layout&quot;:&quot;row-spread&quot;,&quot;x&quot;:670,&quot;y&quot;:2820,&quot;wires&quot;:[]},{&quot;id&quot;:&quot;8db3fac0.99dd48&quot;,&quot;type&quot;:&quot;mqtt-broker&quot;,&quot;z&quot;:&quot;&quot;,&quot;name&quot;:&quot;&quot;,&quot;broker&quot;:&quot;localhost&quot;,&quot;port&quot;:&quot;1883&quot;,&quot;clientid&quot;:&quot;&quot;,&quot;usetls&quot;:false,&quot;compatmode&quot;:false,&quot;keepalive&quot;:&quot;60&quot;,&quot;cleansession&quot;:true,&quot;birthTopic&quot;:&quot;&quot;,&quot;birthQos&quot;:&quot;0&quot;,&quot;birthPayload&quot;:&quot;&quot;,&quot;closeTopic&quot;:&quot;&quot;,&quot;closeQos&quot;:&quot;0&quot;,&quot;closePayload&quot;:&quot;&quot;,&quot;willTopic&quot;:&quot;&quot;,&quot;willQos&quot;:&quot;0&quot;,&quot;willPayload&quot;:&quot;&quot;},{&quot;id&quot;:&quot;37de8fe8.46846&quot;,&quot;type&quot;:&quot;ui_group&quot;,&quot;z&quot;:&quot;&quot;,&quot;name&quot;:&quot;BME680&quot;,&quot;tab&quot;:&quot;53b8c8f9.cfbe48&quot;,&quot;order&quot;:1,&quot;disp&quot;:true,&quot;width&quot;:&quot;6&quot;,&quot;collapse&quot;:false},{&quot;id&quot;:&quot;53b8c8f9.cfbe48&quot;,&quot;type&quot;:&quot;ui_tab&quot;,&quot;z&quot;:&quot;&quot;,&quot;name&quot;:&quot;Home&quot;,&quot;icon&quot;:&quot;dashboard&quot;,&quot;order&quot;:5,&quot;disabled&quot;:false,&quot;hidden&quot;:false}]\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP-MicroPython\/MQTT\/esp_bme680_mqtt_flow.txt\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Demonstration<\/h2>\n\n\n\n<p>Go to your Raspberry Pi IP address followed by <em>:1880\/ui<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;raspberry-pi-ip-address:1880\/ui<\/code><\/pre>\n\n\n\n<p>You should get access to the current BME680 temperature, humidity and pressure readings on the Dashboard. You can use other dashboard-type nodes to display the readings on different ways.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"625\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-Node-RED-BME680-Temperature-Humidity-Pressure-Gas-Air-Quality.png?resize=646%2C625&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 ESP8266 Node-RED BME680 Temperature Humidity Pressure Gas Air Quality\" class=\"wp-image-99518\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-Node-RED-BME680-Temperature-Humidity-Pressure-Gas-Air-Quality.png?w=646&amp;quality=100&amp;strip=all&amp;ssl=1 646w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-ESP8266-Node-RED-BME680-Temperature-Humidity-Pressure-Gas-Air-Quality.png?resize=300%2C290&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 646px) 100vw, 646px\" \/><\/figure><\/div>\n\n\n\n<p>That&#8217;s it! You have your ESP32 or ESP8266 boards publishing BME680 temperature, humidity and pressure readings to Node-RED via MQTT using MicroPython.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>MQTT is a great communication protocol to exchange small amounts of data between IoT devices. In this tutorial you\u2019ve learned how to publish readings from a BME680 sensor with the ESP32 and ESP8266 using MicroPython to different MQTT topics. Then, you can use any device or home automation platform to subscribe to those topics and receive the readings.<\/p>\n\n\n\n<p>Instead of a <a href=\"https:\/\/makeradvisor.com\/tools\/bme680-gas-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME680 sensor<\/a>, you can use any other sensor like <a href=\"https:\/\/randomnerdtutorials.com\/micropython-mqtt-publish-dht11-dht22-esp32-esp8266\/\">DHT11 or DHT22 sensor<\/a> or <a href=\"https:\/\/randomnerdtutorials.com\/micropython-ds18b20-esp32-esp8266\/\">DS18B20 temperature sensor<\/a>.<\/p>\n\n\n\n<p>We have other projects\/tutorials related with the BME680 sensor that you may also like:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">MicroPython: BME280 with ESP32 and ESP8266 (Pressure, Temperature, Humidity)<\/a><\/li><li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">Low Power Weather Station Datalogger using ESP8266 and BME280 with MicroPython<\/a><\/li><\/ul>\n\n\n\n<p class=\"rntbox rntclgray\">Learn more about MicroPython with our eBook: <a href=\"https:\/\/randomnerdtutorials.com\/micropython-programming-with-esp32-and-esp8266\/\">MicroPython Programming using ESP32\/ESP8266<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to program the ESP32 or ESP8266 boards with MicroPython to publish BME680 sensor readings (temperature, humidity, pressure, gas\/air quality) via MQTT to any platform that supports MQTT or &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"MicroPython: MQTT \u2013 Publish BME680 Sensor Readings (ESP32\/ESP8266)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/micropython-mqtt-publish-bme680-esp32-esp8266\/#more-99498\" aria-label=\"Read more about MicroPython: MQTT \u2013 Publish BME680 Sensor Readings (ESP32\/ESP8266)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":99505,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[310,309,264],"tags":[],"class_list":["post-99498","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-micropython","category-0-esp32-micropython","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/MicroPython-ESP32-ESP8266-NodeMCU-MQTT-Publish-BME680-Temperature-Humidity-Pressure-Gas-Readings.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/99498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=99498"}],"version-history":[{"count":0,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/99498\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/99505"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=99498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=99498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=99498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}