{"id":124655,"date":"2023-02-02T11:42:16","date_gmt":"2023-02-02T11:42:16","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=124655"},"modified":"2023-02-02T11:42:18","modified_gmt":"2023-02-02T11:42:18","slug":"micropython-sensor-readings-email-esp32-esp826","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/micropython-sensor-readings-email-esp32-esp826\/","title":{"rendered":"MicroPython: Send Sensor Readings via email with the ESP32\/ESP826 (BME280)"},"content":{"rendered":"\n<p>In this tutorial, you&#8217;ll learn how to program the ESP32 and ESP8266 boards with MicroPython to send sensor readings to your email. As an example, we&#8217;ll send temperature, humidity, and pressure from a BME280 sensor, but you can easily modify the project to use a different sensor.<\/p>\n\n\n<div class=\"wp-block-image\">\n<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\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"MicroPython Send Sensor Readings via email with the ESP32 ESP826 NodeMCU BME280\" class=\"wp-image-124764\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.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<p>Are you going to use a different sensor? We have guides for the following sensors that will help you get started:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-hc-sr04-ultrasonic-esp32-esp8266\/\">MicroPython: <strong>HC-SR04 Ultrasonic Sensor<\/strong> with ESP32 and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme680-esp32-esp8266\/\">MicroPython: <strong>BME680<\/strong> with ESP32 and ESP8266 (Temperature, Humidity, Pressure, Gas)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-ds18b20-esp32-esp8266\/\">MicroPython: <strong>DS18B20<\/strong> Temperature Sensor with ESP32 and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-esp8266-dht11-dht22-micropython-temperature-humidity-sensor\/\">MicroPython: ESP32\/ESP8266 with <strong>DHT11\/DHT22<\/strong> Temperature and Humidity Sensor<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-interrupts-esp32-esp8266\/\">MicroPython: Interrupts with ESP32 and ESP8266 (<strong>PIR Motion Sensor<\/strong>)<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites<\/h2>\n\n\n\n<p class=\"rntbox rntclblue\">New to MicroPython? You can get started here: <a href=\"https:\/\/randomnerdtutorials.com\/getting-started-micropython-esp32-esp8266\/\">Getting Started with MicroPython on ESP32 and ESP8266<\/a>.<\/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\">\n<li>Thonny IDE:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-thonny-micropython-python-ide-esp32-esp8266\/\">Installing and getting started with Thonny IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/flashing-micropython-firmware-esptool-py-esp32-esp8266\/\">Flashing MicroPython Firmware with esptool.py<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>uPyCraft IDE:\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-micropython-esp32-esp8266\/\">Getting Started with uPyCraft IDE<\/a><\/li>\n\n\n\n<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>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/flash-upload-micropython-firmware-esp32-esp8266\/\">Flash\/Upload MicroPython Firmware to ESP32 and ESP8266<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Or, if you&#8217;re familiar with VS Code, you may want to use the PyMakr extension:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-esp32-esp8266-vs-code-pymakr\/\">MicroPython: Program ESP32\/ESP8266 using VS Code and Pymakr<\/a><\/li>\n<\/ul>\n\n\n\n<p>For a comparison between different MicroPython IDEs, read: <a href=\"https:\/\/randomnerdtutorials.com\/micropython-ides-esp32-esp8266\/\">MicroPython IDEs for ESP32 and ESP8266<\/a>.<\/p>\n\n\n\n<p class=\"rntbox rntclblue\">Learn more about MicroPython:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/micropython-programming-with-esp32-and-esp8266\/\">MicroPython Programming with ESP32 and ESP8266 eBook<\/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\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32<\/a>&nbsp;(read&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noreferrer noopener\">Best ESP32 development boards<\/a>) or&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/esp8266-esp-12e-nodemcu-wi-fi-development-board\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/bme280-sensor-module\/\" target=\"_blank\" rel=\"noreferrer noopener\">BME280<\/a>&nbsp;\u2013&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">BME280 with ESP32\/ESP8266 Guide<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jumper wires<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noreferrer noopener\">Breadboard<\/a><\/li>\n<\/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<h3 class=\"wp-block-heading\">uMail Module<\/h3>\n\n\n\n<p>To easily send emails with MicroPython, we&#8217;ll use a module called <a href=\"https:\/\/github.com\/shawwwn\/uMail\" target=\"_blank\" rel=\"noopener\">uMail<\/a>. This module is not part of the standard collection of MicroPython libraries, so we&#8217;ll need to upload it separately to our board\u2014we&#8217;ll provide instructions for this later in the tutorial.<\/p>\n\n\n\n<p>To get familiar with sending emails using this library, take a look at our tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-send-emails-esp32-esp826\/\" title=\"\">MicroPython: Send Emails with the ESP32\/ESP826<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">BME280 Module<\/h3>\n\n\n\n<p>To read from the BME280 sensor, we&#8217;ll use a module that&#8217;s not also part of the standard MicroPython libraries by default. So, we&#8217;ll need to upload it to the board before start writing the code. The BME280 module <a href=\"https:\/\/github.com\/RuiSantosdotme\/ESP-MicroPython\/blob\/master\/code\/WiFi\/HTTP_Client_IFTTT_BME280\/BME280.py\" target=\"_blank\" rel=\"noopener\">can be found here<\/a>.<\/p>\n\n\n\n<p>For a getting started guide to learn how to interface the BME280 with the ESP32\/ESP8266 using MicroPython, you can read the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">MicroPython: BME280 with ESP32 and ESP8266 (Pressure, Temperature, Humidity)<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Sender Email (New Account)<\/h3>\n\n\n\n<p>We recommend creating a new email account to send the emails to your main personal email address. <strong>Do not use your main personal email to send emails via ESP32 or ESP8266<\/strong>. If something goes wrong in your code or if by mistake you make too many requests, you can be banned or have your account temporarily disabled. We recommend using a Gmail account, but other email providers should also work.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"create-app-password\">Create an App Password<\/h3>\n\n\n\n<p>You need to create an app password so that new devices can send emails using your Gmail account. An App Password is a 16-digit passcode that gives a less secure app or device permission to access your Google Account. <a href=\"https:\/\/support.google.com\/accounts\/answer\/185833\" target=\"_blank\" rel=\"noreferrer noopener\">Learn more about sign-in with app passwords here<\/a>.<\/p>\n\n\n\n<p>You can follow <a href=\"https:\/\/randomnerdtutorials.com\/micropython-send-emails-esp32-esp826\/#create-app-password\" title=\"\"><strong>these instructions<\/strong> to learn how to create your app password<\/a>.<\/p>\n\n\n\n<p>If you&#8217;re using another email provider, check how to create an app password. You should be able to find the instructions with a quick google search &#8220;<strong>your_email_provider<\/strong> + create app password&#8221;.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wiring the BME280<\/h2>\n\n\n\n<p>In this tutorial, we&#8217;ll create a sample project that sends BME280 sensor readings to your email. So, you need to wire the BME280 sensor to your board. Follow one of the next schematic diagrams.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">ESP32 with BME280<\/h4>\n\n\n\n<p>We&#8217;re going to use I2C communication with the BME280 sensor module. Wire the sensor to the default ESP32 SCL (<span class=\"rnthl rntclblue\">GPIO 22<\/span>) and SDA (<span class=\"rnthl rntclgreen\">GPIO 21<\/span>) pins, as shown in the following schematic diagram.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"675\" height=\"670\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit_f.png?resize=675%2C670&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit\" class=\"wp-image-99755\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit_f.png?w=675&amp;quality=100&amp;strip=all&amp;ssl=1 675w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit_f.png?resize=300%2C298&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/10\/ESP32-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit_f.png?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 675px) 100vw, 675px\" \/><\/figure><\/div>\n\n\n<h4 class=\"wp-block-heading\">ESP8266 with BME280 <\/h4>\n\n\n\n<p>We&#8217;re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the ESP8266&nbsp;SDA (<span class=\"rnthl rntclgreen\">GPIO 4<\/span>)&nbsp;and&nbsp;SCL (<span class=\"rnthl rntclblue\">GPIO 5<\/span>)&nbsp;pins, as shown in the following schematic diagram.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"675\" height=\"531\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-NodeMCU-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit.png?resize=675%2C531&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP8266 NodeMCU BME280 Sensor Temperature Humidity Pressure Wiring Diagram Circuit\" class=\"wp-image-98049\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-NodeMCU-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit.png?w=675&amp;quality=100&amp;strip=all&amp;ssl=1 675w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2020\/07\/ESP8266-NodeMCU-BME280-Sensor-Temperature-Humidity-Pressure-Wiring-Diagram-Circuit.png?resize=300%2C236&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 675px) 100vw, 675px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\">Not familiar with the BME280 with the ESP32\/ESP8266 using MicroPython? Read this tutorial: <a href=\"https:\/\/randomnerdtutorials.com\/micropython-bme280-esp32-esp8266\/\">MicroPython: BME280 with ESP32 and ESP8266 (Pressure, Temperature, Humidity)<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Uploading the uMail Module<\/h2>\n\n\n\n<p>To send the emails, we&#8217;ll use the uMail module. You can check its <a href=\"https:\/\/github.com\/shawwwn\/uMail\" target=\"_blank\" rel=\"noopener\">Github page and several examples here<\/a>. This library isn\u2019t part of the standard MicroPython library by default. So, you need to upload the following file to your ESP32\/ESP8266 board (save it with the name <span class=\"rnthl rntliteral\">umail.py<\/span>) before using the library.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Complete project details: https:\/\/RandomNerdTutorials.com\/micropython-send-emails-esp32-esp826\/\n# uMail (MicroMail) for MicroPython\n# Copyright (c) 2018 Shawwwn &lt;shawwwn1@gmai.com&gt; https:\/\/github.com\/shawwwn\/uMail\/blob\/master\/umail.py\n# License: MIT\nimport usocket\n\nDEFAULT_TIMEOUT = 10 # sec\nLOCAL_DOMAIN = '127.0.0.1'\nCMD_EHLO = 'EHLO'\nCMD_STARTTLS = 'STARTTLS'\nCMD_AUTH = 'AUTH'\nCMD_MAIL = 'MAIL'\nAUTH_PLAIN = 'PLAIN'\nAUTH_LOGIN = 'LOGIN'\n\nclass SMTP:\n    def cmd(self, cmd_str):\n        sock = self._sock;\n        sock.write('%s\\r\\n' % cmd_str)\n        resp = []\n        next = True\n        while next:\n            code = sock.read(3)\n            next = sock.read(1) == b'-'\n            resp.append(sock.readline().strip().decode())\n        return int(code), resp\n\n    def __init__(self, host, port, ssl=False, username=None, password=None):\n        import ssl\n        self.username = username\n        addr = usocket.getaddrinfo(host, port)[0][-1]\n        sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)\n        sock.settimeout(DEFAULT_TIMEOUT)\n        sock.connect(addr)\n        if ssl:\n            sock = ssl.wrap_socket(sock)\n        code = int(sock.read(3))\n        sock.readline()\n        assert code==220, 'cant connect to server %d, %s' % (code, resp)\n        self._sock = sock\n\n        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)\n        assert code==250, '%d' % code\n        if not ssl and CMD_STARTTLS in resp:\n            code, resp = self.cmd(CMD_STARTTLS)\n            assert code==220, 'start tls failed %d, %s' % (code, resp)\n            self._sock = ssl.wrap_socket(sock)\n\n        if username and password:\n            self.login(username, password)\n\n    def login(self, username, password):\n        self.username = username\n        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)\n        assert code==250, '%d, %s' % (code, resp)\n\n        auths = None\n        for feature in resp:\n            if feature[:4].upper() == CMD_AUTH:\n                auths = feature[4:].strip('=').upper().split()\n        assert auths!=None, &quot;no auth method&quot;\n\n        from ubinascii import b2a_base64 as b64\n        if AUTH_PLAIN in auths:\n            cren = b64(&quot;\\0%s\\0%s&quot; % (username, password))[:-1].decode()\n            code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, cren))\n        elif AUTH_LOGIN in auths:\n            code, resp = self.cmd(&quot;%s %s %s&quot; % (CMD_AUTH, AUTH_LOGIN, b64(username)[:-1].decode()))\n            assert code==334, 'wrong username %d, %s' % (code, resp)\n            code, resp = self.cmd(b64(password)[:-1].decode())\n        else:\n            raise Exception(&quot;auth(%s) not supported &quot; % ', '.join(auths))\n\n        assert code==235 or code==503, 'auth error %d, %s' % (code, resp)\n        return code, resp\n\n    def to(self, addrs, mail_from=None):\n        mail_from = self.username if mail_from==None else mail_from\n        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)\n        assert code==250, '%d' % code\n        code, resp = self.cmd('MAIL FROM: &lt;%s&gt;' % mail_from)\n        assert code==250, 'sender refused %d, %s' % (code, resp)\n\n        if isinstance(addrs, str):\n            addrs = [addrs]\n        count = 0\n        for addr in addrs:\n            code, resp = self.cmd('RCPT TO: &lt;%s&gt;' % addr)\n            if code!=250 and code!=251:\n                print('%s refused, %s' % (addr, resp))\n                count += 1\n        assert count!=len(addrs), 'recipient refused, %d, %s' % (code, resp)\n\n        code, resp = self.cmd('DATA')\n        assert code==354, 'data refused, %d, %s' % (code, resp)\n        return code, resp\n\n    def write(self, content):\n        self._sock.write(content)\n\n    def send(self, content=''):\n        if content:\n            self.write(content)\n        self._sock.write('\\r\\n.\\r\\n') # the five letter sequence marked for ending\n        line = self._sock.readline()\n        return (int(line[:3]), line[4:].strip().decode())\n\n    def quit(self):\n        self.cmd(&quot;QUIT&quot;)\n        self._sock.close()\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/master\/Projects\/ESP-MicroPython\/umail.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Regardless of the IDE you&#8217;re using, these are the general instructions to upload the uMail library to your board:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>First, make sure your board is running MicroPython firmware\u2014check the <a href=\"#prerequisites\">Prerequisites section<\/a>.<\/li>\n\n\n\n<li>Create a new file in your IDE with the name <span class=\"rnthl rntliteral\">umail.py<\/span> and paste the previous code there. Save that file.<\/li>\n\n\n\n<li>Establish a serial communication with your board using your IDE.<\/li>\n\n\n\n<li>Upload the <span class=\"rnthl rntliteral\">umail.py<\/span> file to your board.<\/li>\n\n\n\n<li>At this point, the library should have been successfully uploaded to your board. Now, you can use the library functionalities in your code by importing the library: <span class=\"rnthl rntliteral\">import umail<\/span>.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Uploading the BME280 Module<\/h2>\n\n\n\n<p>To get temperature, humidity, and pressure from the BME280 sensor, we&#8217;ll use the following module (name it <span class=\"rnthl rntliteral\">BME280.py<\/span> before uploading it to your board).<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\">from machine import I2C\nimport time\n\n# BME280 default address.\nBME280_I2CADDR = 0x76\n\n# Operating Modes\nBME280_OSAMPLE_1 = 1\nBME280_OSAMPLE_2 = 2\nBME280_OSAMPLE_4 = 3\nBME280_OSAMPLE_8 = 4\nBME280_OSAMPLE_16 = 5\n\n# BME280 Registers\n\nBME280_REGISTER_DIG_T1 = 0x88  # Trimming parameter registers\nBME280_REGISTER_DIG_T2 = 0x8A\nBME280_REGISTER_DIG_T3 = 0x8C\n\nBME280_REGISTER_DIG_P1 = 0x8E\nBME280_REGISTER_DIG_P2 = 0x90\nBME280_REGISTER_DIG_P3 = 0x92\nBME280_REGISTER_DIG_P4 = 0x94\nBME280_REGISTER_DIG_P5 = 0x96\nBME280_REGISTER_DIG_P6 = 0x98\nBME280_REGISTER_DIG_P7 = 0x9A\nBME280_REGISTER_DIG_P8 = 0x9C\nBME280_REGISTER_DIG_P9 = 0x9E\n\nBME280_REGISTER_DIG_H1 = 0xA1\nBME280_REGISTER_DIG_H2 = 0xE1\nBME280_REGISTER_DIG_H3 = 0xE3\nBME280_REGISTER_DIG_H4 = 0xE4\nBME280_REGISTER_DIG_H5 = 0xE5\nBME280_REGISTER_DIG_H6 = 0xE6\nBME280_REGISTER_DIG_H7 = 0xE7\n\nBME280_REGISTER_CHIPID = 0xD0\nBME280_REGISTER_VERSION = 0xD1\nBME280_REGISTER_SOFTRESET = 0xE0\n\nBME280_REGISTER_CONTROL_HUM = 0xF2\nBME280_REGISTER_CONTROL = 0xF4\nBME280_REGISTER_CONFIG = 0xF5\nBME280_REGISTER_PRESSURE_DATA = 0xF7\nBME280_REGISTER_TEMP_DATA = 0xFA\nBME280_REGISTER_HUMIDITY_DATA = 0xFD\n\n\nclass Device:\n  &quot;&quot;&quot;Class for communicating with an I2C device.\n\n  Allows reading and writing 8-bit, 16-bit, and byte array values to\n  registers on the device.&quot;&quot;&quot;\n\n  def __init__(self, address, i2c):\n    &quot;&quot;&quot;Create an instance of the I2C device at the specified address using\n    the specified I2C interface object.&quot;&quot;&quot;\n    self._address = address\n    self._i2c = i2c\n\n  def writeRaw8(self, value):\n    &quot;&quot;&quot;Write an 8-bit value on the bus (without register).&quot;&quot;&quot;\n    value = value &amp; 0xFF\n    self._i2c.writeto(self._address, value)\n\n  def write8(self, register, value):\n    &quot;&quot;&quot;Write an 8-bit value to the specified register.&quot;&quot;&quot;\n    b=bytearray(1)\n    b[0]=value &amp; 0xFF\n    self._i2c.writeto_mem(self._address, register, b)\n\n  def write16(self, register, value):\n    &quot;&quot;&quot;Write a 16-bit value to the specified register.&quot;&quot;&quot;\n    value = value &amp; 0xFFFF\n    b=bytearray(2)\n    b[0]= value &amp; 0xFF\n    b[1]= (value&gt;&gt;8) &amp; 0xFF\n    self.i2c.writeto_mem(self._address, register, value)\n\n  def readRaw8(self):\n    &quot;&quot;&quot;Read an 8-bit value on the bus (without register).&quot;&quot;&quot;\n    return int.from_bytes(self._i2c.readfrom(self._address, 1),'little') &amp; 0xFF\n\n  def readU8(self, register):\n    &quot;&quot;&quot;Read an unsigned byte from the specified register.&quot;&quot;&quot;\n    return int.from_bytes(\n        self._i2c.readfrom_mem(self._address, register, 1),'little') &amp; 0xFF\n\n  def readS8(self, register):\n    &quot;&quot;&quot;Read a signed byte from the specified register.&quot;&quot;&quot;\n    result = self.readU8(register)\n    if result &gt; 127:\n      result -= 256\n    return result\n\n  def readU16(self, register, little_endian=True):\n    &quot;&quot;&quot;Read an unsigned 16-bit value from the specified register, with the\n    specified endianness (default little endian, or least significant byte\n    first).&quot;&quot;&quot;\n    result = int.from_bytes(\n        self._i2c.readfrom_mem(self._address, register, 2),'little') &amp; 0xFFFF\n    if not little_endian:\n      result = ((result &lt;&lt; 8) &amp; 0xFF00) + (result &gt;&gt; 8)\n    return result\n\n  def readS16(self, register, little_endian=True):\n    &quot;&quot;&quot;Read a signed 16-bit value from the specified register, with the\n    specified endianness (default little endian, or least significant byte\n    first).&quot;&quot;&quot;\n    result = self.readU16(register, little_endian)\n    if result &gt; 32767:\n      result -= 65536\n    return result\n\n  def readU16LE(self, register):\n    &quot;&quot;&quot;Read an unsigned 16-bit value from the specified register, in little\n    endian byte order.&quot;&quot;&quot;\n    return self.readU16(register, little_endian=True)\n\n  def readU16BE(self, register):\n    &quot;&quot;&quot;Read an unsigned 16-bit value from the specified register, in big\n    endian byte order.&quot;&quot;&quot;\n    return self.readU16(register, little_endian=False)\n\n  def readS16LE(self, register):\n    &quot;&quot;&quot;Read a signed 16-bit value from the specified register, in little\n    endian byte order.&quot;&quot;&quot;\n    return self.readS16(register, little_endian=True)\n\n  def readS16BE(self, register):\n    &quot;&quot;&quot;Read a signed 16-bit value from the specified register, in big\n    endian byte order.&quot;&quot;&quot;\n    return self.readS16(register, little_endian=False)\n\n\nclass BME280:\n  def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,\n               **kwargs):\n    # Check that mode is valid.\n    if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,\n                    BME280_OSAMPLE_8, BME280_OSAMPLE_16]:\n        raise ValueError(\n            'Unexpected mode value {0}. Set mode to one of '\n            'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or '\n            'BME280_ULTRAHIGHRES'.format(mode))\n    self._mode = mode\n    # Create I2C device.\n    if i2c is None:\n      raise ValueError('An I2C object is required.')\n    self._device = Device(address, i2c)\n    # Load calibration values.\n    self._load_calibration()\n    self._device.write8(BME280_REGISTER_CONTROL, 0x3F)\n    self.t_fine = 0\n\n  def _load_calibration(self):\n\n    self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)\n    self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)\n    self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)\n\n    self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)\n    self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)\n    self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)\n    self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)\n    self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)\n    self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)\n    self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)\n    self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)\n    self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)\n\n    self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)\n    self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)\n    self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)\n    self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)\n\n    h4 = self._device.readS8(BME280_REGISTER_DIG_H4)\n    h4 = (h4 &lt;&lt; 24) &gt;&gt; 20\n    self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) &amp; 0x0F)\n\n    h5 = self._device.readS8(BME280_REGISTER_DIG_H6)\n    h5 = (h5 &lt;&lt; 24) &gt;&gt; 20\n    self.dig_H5 = h5 | (\n        self._device.readU8(BME280_REGISTER_DIG_H5) &gt;&gt; 4 &amp; 0x0F)\n\n  def read_raw_temp(self):\n    &quot;&quot;&quot;Reads the raw (uncompensated) temperature from the sensor.&quot;&quot;&quot;\n    meas = self._mode\n    self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)\n    meas = self._mode &lt;&lt; 5 | self._mode &lt;&lt; 2 | 1\n    self._device.write8(BME280_REGISTER_CONTROL, meas)\n    sleep_time = 1250 + 2300 * (1 &lt;&lt; self._mode)\n\n    sleep_time = sleep_time + 2300 * (1 &lt;&lt; self._mode) + 575\n    sleep_time = sleep_time + 2300 * (1 &lt;&lt; self._mode) + 575\n    time.sleep_us(sleep_time)  # Wait the required time\n    msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)\n    lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)\n    xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)\n    raw = ((msb &lt;&lt; 16) | (lsb &lt;&lt; 8) | xlsb) &gt;&gt; 4\n    return raw\n\n  def read_raw_pressure(self):\n    &quot;&quot;&quot;Reads the raw (uncompensated) pressure level from the sensor.&quot;&quot;&quot;\n    &quot;&quot;&quot;Assumes that the temperature has already been read &quot;&quot;&quot;\n    &quot;&quot;&quot;i.e. that enough delay has been provided&quot;&quot;&quot;\n    msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)\n    lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)\n    xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)\n    raw = ((msb &lt;&lt; 16) | (lsb &lt;&lt; 8) | xlsb) &gt;&gt; 4\n    return raw\n\n  def read_raw_humidity(self):\n    &quot;&quot;&quot;Assumes that the temperature has already been read &quot;&quot;&quot;\n    &quot;&quot;&quot;i.e. that enough delay has been provided&quot;&quot;&quot;\n    msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)\n    lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)\n    raw = (msb &lt;&lt; 8) | lsb\n    return raw\n\n  def read_temperature(self):\n    &quot;&quot;&quot;Get the compensated temperature in 0.01 of a degree celsius.&quot;&quot;&quot;\n    adc = self.read_raw_temp()\n    var1 = ((adc &gt;&gt; 3) - (self.dig_T1 &lt;&lt; 1)) * (self.dig_T2 &gt;&gt; 11)\n    var2 = ((\n        (((adc &gt;&gt; 4) - self.dig_T1) * ((adc &gt;&gt; 4) - self.dig_T1)) &gt;&gt; 12) *\n        self.dig_T3) &gt;&gt; 14\n    self.t_fine = var1 + var2\n    return (self.t_fine * 5 + 128) &gt;&gt; 8\n\n  def read_pressure(self):\n    &quot;&quot;&quot;Gets the compensated pressure in Pascals.&quot;&quot;&quot;\n    adc = self.read_raw_pressure()\n    var1 = self.t_fine - 128000\n    var2 = var1 * var1 * self.dig_P6\n    var2 = var2 + ((var1 * self.dig_P5) &lt;&lt; 17)\n    var2 = var2 + (self.dig_P4 &lt;&lt; 35)\n    var1 = (((var1 * var1 * self.dig_P3) &gt;&gt; 8) +\n            ((var1 * self.dig_P2) &gt;&gt; 12))\n    var1 = (((1 &lt;&lt; 47) + var1) * self.dig_P1) &gt;&gt; 33\n    if var1 == 0:\n      return 0\n    p = 1048576 - adc\n    p = (((p &lt;&lt; 31) - var2) * 3125) \/\/ var1\n    var1 = (self.dig_P9 * (p &gt;&gt; 13) * (p &gt;&gt; 13)) &gt;&gt; 25\n    var2 = (self.dig_P8 * p) &gt;&gt; 19\n    return ((p + var1 + var2) &gt;&gt; 8) + (self.dig_P7 &lt;&lt; 4)\n\n  def read_humidity(self):\n    adc = self.read_raw_humidity()\n    # print 'Raw humidity = {0:d}'.format (adc)\n    h = self.t_fine - 76800\n    h = (((((adc &lt;&lt; 14) - (self.dig_H4 &lt;&lt; 20) - (self.dig_H5 * h)) +\n         16384) &gt;&gt; 15) * (((((((h * self.dig_H6) &gt;&gt; 10) * (((h *\n                          self.dig_H3) &gt;&gt; 11) + 32768)) &gt;&gt; 10) + 2097152) *\n                          self.dig_H2 + 8192) &gt;&gt; 14))\n    h = h - (((((h &gt;&gt; 15) * (h &gt;&gt; 15)) &gt;&gt; 7) * self.dig_H1) &gt;&gt; 4)\n    h = 0 if h &lt; 0 else h\n    h = 419430400 if h &gt; 419430400 else h\n    return h &gt;&gt; 12\n\n  @property\n  def temperature(self):\n    &quot;Return the temperature in degrees.&quot;\n    t = self.read_temperature()\n    ti = t \/\/ 100\n    td = t - ti * 100\n    return &quot;{}.{:02d}C&quot;.format(ti, td)\n\n  @property\n  def pressure(self):\n    &quot;Return the temperature in hPa.&quot;\n    p = self.read_pressure() \/\/ 256\n    pi = p \/\/ 100\n    pd = p - pi * 100\n    return &quot;{}.{:02d}hPa&quot;.format(pi, pd)\n\n  @property\n  def humidity(self):\n    &quot;Return the humidity in percent.&quot;\n    h = self.read_humidity()\n    hi = h \/\/ 1024\n    hd = h * 100 \/\/ 1024 - hi * 100\n    return &quot;{}.{:02d}%&quot;.format(hi, hd)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/ESP-MicroPython\/raw\/master\/code\/WiFi\/HTTP_Client_IFTTT_BME280\/BME280.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>Regardless of the IDE you&#8217;re using, these are the general instructions to upload the BME280 library to your board:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>First, make sure your board is running MicroPython firmware\u2014check the <a href=\"#prerequisites\">Prerequisites section<\/a>.<\/li>\n\n\n\n<li>Create a new file in your IDE with the name <span class=\"rnthl rntliteral\">BME280.py<\/span> and paste the previous code there. Save that file.<\/li>\n\n\n\n<li>Establish a serial communication with your board using your IDE.<\/li>\n\n\n\n<li>Upload the <span class=\"rnthl rntliteral\">BME280.py<\/span> file to your board.<\/li>\n\n\n\n<li>At this point, the library should have been successfully uploaded to your board. Now, you can use the library functionalities in your code by importing the library: <span class=\"rnthl rntliteral\">import BME280<\/span>.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Sending Sensor Readings via Email &#8211; MicroPython &#8211; Code<\/h2>\n\n\n\n<p>Now you should have uploaded the <span class=\"rnthl rntliteral\">umail.py<\/span>, and <span class=\"rnthl rntliteral\">BME280.py<\/span> files to your board to be able to send emails and read from the BME280 sensor. <\/p>\n\n\n\n<p>The following script sends a new email with the current sensor readings when the ESP32\/ESP8266 board first boots\/resets.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Complete project details: https:\/\/RandomNerdTutorials.com\/micropython-sensor-readings-email-esp32-esp826\/\nimport umail # Micropython lib to send emails: https:\/\/github.com\/shawwwn\/uMail\nimport network\nimport BME280\nfrom machine import Pin, SoftI2C\n\n# Your network credentials\nssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'\n\n# Email details\nsender_email = 'REPLACE_WITH_THE_SENDER_EMAIL'\nsender_name = 'ESP32' #sender name\nsender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'\nrecipient_email ='REPLACE_WITH_THE_RECIPIENT_EMAIL'\nemail_subject ='BME280 Sensor Readings'\n\n# BME280 pin assignment - ESP32\ni2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)\n# BME280 pin assignment - ESP8266\n#i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000)\nbme = BME280.BME280(i2c=i2c)\n\ndef read_bme_sensor():\n  try:\n    temp = str(bme.temperature[:-1]) + &quot; \u00baC&quot;\n    #uncomment for temperature in Fahrenheit\n    #temp = str((bme.read_temperature()\/100) * (9\/5) + 32) + &quot; \u6f5eF&quot;\n    hum = str(bme.humidity[:-1]) + &quot; %&quot;\n    pres = str(bme.pressure[:-3]) + &quot; hPa&quot;\n\n    return temp, hum, pres\n    #else:\n    #  return('Invalid sensor readings.')\n  except OSError as e:\n    return('Failed to read sensor.')\n  \ndef connect_wifi(ssid, password):\n  #Connect to your network\n  station = network.WLAN(network.STA_IF)\n  station.active(True)\n  station.connect(ssid, password)\n  while station.isconnected() == False:\n    pass\n  print('Connection successful')\n  print(station.ifconfig())\n    \n# Connect to your network\nconnect_wifi(ssid, password)\n\n# Get sensor readings\ntemp, hum, pres = read_bme_sensor()\nprint(temp)\nprint(hum)\nprint(pres)\n\n# Send the email\nsmtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port\nsmtp.login(sender_email, sender_app_password)\nsmtp.to(recipient_email)\nsmtp.write(&quot;From:&quot; + sender_name + &quot;&lt;&quot;+ sender_email+&quot;&gt;\\n&quot;)\nsmtp.write(&quot;Subject:&quot; + email_subject + &quot;\\n&quot;)\nsmtp.write(&quot;Temperature &quot; + temp + &quot;\\n&quot;)\nsmtp.write(&quot;Humidity &quot; + hum + &quot;\\n&quot;)\nsmtp.write(&quot;Pressure &quot; + pres + &quot;\\n&quot;)\nsmtp.send()\nsmtp.quit()\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\/esp_send_email_bme280.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>You need to insert your own details in the code before uploading the code to the board: SSID and password, sender email, sender name, and corresponding app password, recipient&#8217;s email, and email subject.<\/p>\n\n\n\n<p>After inserting all your details you can upload the code to your board. The file with the code needs to be named <span class=\"rnthl rntliteral\">main.py<\/span>, otherwise, it will not work.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#demonstration\">Demonstration <\/a>section.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Including Libraries<\/h4>\n\n\n\n<p>First, include the required libraries. The <span class=\"rnthl rntliteral\">umail<\/span> library, which we loaded previously to the board, so that we can send emails, and the <span class=\"rnthl rntliteral\">network<\/span> library so that we can set the ESP32\/ESP8266 as a wi-fi station to be able to connect to the internet (local network). Additionally, you need to import the <span class=\"rnthl rntliteral\">BME280<\/span> module to read from the BME280 sensor, and the <span class=\"rnthl rntliteral\">Pin<\/span> and <span class=\"rnthl rntliteral\">I2C<\/span> classes from the <span class=\"rnthl rntliteral\">machine<\/span> module to establish an I2C communication with the sensor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import umail # Micropython lib to send emails: https:\/\/github.com\/shawwwn\/uMail\nimport network\nimport BME280\nfrom machine import Pin, SoftI2C<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Network Credentials<\/h4>\n\n\n\n<p>Insert your network credentials, SSID, and password, on the following variables so that your board can connect to the internet:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>ssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Email Details<\/h4>\n\n\n\n<p>Insert the email details: sender email, sender name, and corresponding app password. You really need to create an app password\u2014using the regular email password won&#8217;t work, <strong><a href=\"https:\/\/randomnerdtutorials.com\/micropython-send-emails-esp32-esp826\/#create-app-password\" title=\"\">check these instructions<\/a><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Email details\nsender_email = 'REPLACE_WITH_THE_SENDER_EMAIL'\nsender_name = 'ESP32' #sender name\nsender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'<\/code><\/pre>\n\n\n\n<p>Insert the recipient&#8217;s email on the <span class=\"rnthl rntliteral\">recipient_email<\/span> variable:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>recipient_email ='REPLACE_WITH_THE_RECIPIENT_EMAIL'<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">BME280<\/h4>\n\n\n\n<p>The email subject is set to <span class=\"rnthl rntliteral\">BME280 Sensor Readings<\/span>, but you can change it on the <span class=\"rnthl rntliteral\">email_subject<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>email_subject ='BME280 Sensor Readings'<\/code><\/pre>\n\n\n\n<p>Create an i2c object using the board I2C pins. The ESP32 uses GPIO 22 and GPIO 21 as I2C pins.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)<\/code><\/pre>\n\n\n\n<p>If you&#8217;re using an ESP8266 board, you should use GPIO 4 and GPIO 5 instead. <\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000)<\/code><\/pre>\n\n\n\n<p>If you&#8217;re using a board with different I2C pins, make sure that you modify this previous line.<\/p>\n\n\n\n<p>Now that we have an <span class=\"rnthl rntliteral\">i2c<\/span> object, we can create a <span class=\"rnthl rntliteral\">BME280<\/span> object (in this case called <span class=\"rnthl rntliteral\">bme<\/span>) on those pins.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>bme = BME280.BME280(i2c=i2c)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Reading BME280: Temperature, Humidity, and Pressure<\/h4>\n\n\n\n<p>To read from the BME280 sensor, we created a function called <span class=\"rnthl rntliteral\">read_bme_sensor()<\/span> that returns the temperature, humidity, and pressure as strings with the corresponding units, which is the ideal format to use in the email body.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def read_bme_sensor():\n  try:\n    temp = str(bme.temperature&#091;:-1]) + \" \u00baC\"\n    #uncomment for temperature in Fahrenheit\n    #temp = str((bme.read_temperature()\/100) * (9\/5) + 32) + \" \u00baF\"\n    hum = str(bme.humidity&#091;:-1]) + \" %\"\n    pres = str(bme.pressure&#091;:-3]) + \" hPa\"\n\n    return temp, hum, pres\n    #else:\n    #  return('Invalid sensor readings.')\n  except OSError as e:\n    return('Failed to read sensor.')<\/code><\/pre>\n\n\n\n<p>By default, the function returns the temperature in Celcius degrees. If you want to get the temperature in Fahrenheit, you just need to uncomment the following line:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#temp = str((bme.read_temperature()\/100) * (9\/5) + 32) + \" \u00baF\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Connecting to Wi-Fi<\/h4>\n\n\n\n<p>To connect the board to Wi-Fi, we created a function called <span class=\"rnthl rntliteral\">connect_wifi()<\/span> that accepts as arguments the SSID and password of the network you want to connect to. You should call this function later to actually connect the ESP board to the internet.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def connect_wifi(ssid, password):\n  #Connect to your network\n  station = network.WLAN(network.STA_IF)\n  station.active(True)\n  station.connect(ssid, password)\n  while station.isconnected() == False:\n    pass\n  print('Connection successful')\n  print(station.ifconfig())<\/code><\/pre>\n\n\n\n<p>Before sending the email, we need to connect the ESP32\/ESP8266 to the internet, so call the <span class=\"rnthl rntliteral\">connect_wifi()<\/span> function (pass as arguments the ssid and password).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Connect to your network\nconnect_wifi(ssid, password)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Getting New Readings<\/h4>\n\n\n\n<p>To get readings from the sensor in the format we want, we just need to call the <span class=\"rnthl rntliteral\">read_bme_sensor()<\/span> function we created previously. The temperature, humidity and pressure are saved on the <span class=\"rnthl rntliteral\">temp<\/span>, <span class=\"rnthl rntliteral\">hum<\/span>, and <span class=\"rnthl rntliteral\">pres<\/span> variables. These are string variables that already include the units (\u00baC, %, and hPa). The following lines, get the latest readings and print them on the shell.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Get sensor readings\ntemp, hum, pres = read_bme_sensor()\nprint(temp)\nprint(hum)\nprint(pres)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Sending the Email<\/h4>\n\n\n\n<p>Now, we can finally start preparing and sending the email.<\/p>\n\n\n\n<p>Start by creating an SMTP client using your email provider SMTP settings called <span class=\"rnthl rntliteral\">smtp<\/span>. Here we&#8217;re using a Gmail account. Change the settings if you&#8217;re using a different email provider\u2014set the server, port, and if SSL is required or not.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port<\/code><\/pre>\n\n\n\n<p>Then, login into your account using the <span class=\"rnthl rntliteral\">login()<\/span> method on the <span class=\"rnthl rntliteral\">smtp<\/span> client\u2014pass as arguments the email and corresponding app password.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.login(sender_email, sender_app_password)<\/code><\/pre>\n\n\n\n<p>Set the recipient using the <span class=\"rnthl rntliteral\">to()<\/span> method and pass the recipient&#8217;s email as an argument:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.to(recipient_email)<\/code><\/pre>\n\n\n\n<p>Then, use the <span class=\"rnthl rntliteral\">write()<\/span> method to write the email. You can use this method as follows to set the sender name.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.write(\"From:\" + sender_name + \"&lt;\"+ sender_email+\"&gt;\\n\")<\/code><\/pre>\n\n\n\n<p>And you can use the following line to set the email subject.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.write(\"Subject:\" + email_subject + \"\\n\")<\/code><\/pre>\n\n\n\n<p>Finally, you can actually write your email content. We&#8217;re just sending the temperature, humidity, and pressure values in the email body, but you can add more text or even some HTML to format the email body. The <span class=\"rnthl rntliteral\">write()<\/span> method sends the email to the SMTP server.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.write(\"Temperature \" + temp + \"\\n\")\nsmtp.write(\"Humidity \" + hum + \"\\n\")\nsmtp.write(\"Pressure \" + pres + \"\\n\")<\/code><\/pre>\n\n\n\n<p>If you need to send a long string as the email body, break the email message into smaller chunks and send each chunk using the <span class=\"rnthl rntliteral\">write()<\/span> method\u2014<a href=\"https:\/\/github.com\/shawwwn\/uMail#api-docs\" target=\"_blank\" rel=\"noopener\">see the uMail library documentation<\/a>.<\/p>\n\n\n\n<p>Finally, use the <span class=\"rnthl rntliteral\">send()<\/span> method to make the SMTP server send the email to the recipient.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.send()<\/code><\/pre>\n\n\n\n<p>In the end, close the connection with the server using the <span class=\"rnthl rntliteral\">quit()<\/span> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>smtp.quit()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"demonstration\">Demonstration<\/h2>\n\n\n\n<p>After uploading the <span class=\"rnthl rntliteral\">umail<\/span>, and the <span class=\"rnthl rntliteral\">BME280<\/span> modules, and the <span class=\"rnthl rntliteral\">main.py<\/span> script to your board, run the code or reset\/restart your board. You should get a similar message in the shell indicating that your board connected successfully to the internet, and the current sensor readings.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"552\" height=\"105\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/Send-Sensor-Readings-via-Email-Micropython-shell.png?resize=552%2C105&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Sensor readings via email micropython shell\" class=\"wp-image-124756\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/Send-Sensor-Readings-via-Email-Micropython-shell.png?w=552&amp;quality=100&amp;strip=all&amp;ssl=1 552w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/Send-Sensor-Readings-via-Email-Micropython-shell.png?resize=300%2C57&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 552px) 100vw, 552px\" \/><\/figure><\/div>\n\n\n<p>After a while, you should receive a new email on the recipient&#8217;s email account.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"712\" height=\"399\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email.jpg?resize=712%2C399&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"email sent from EPS32 ESP8266 NodeMCU using MicroPython inbox\" class=\"wp-image-124757\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email.jpg?w=712&amp;quality=100&amp;strip=all&amp;ssl=1 712w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email.jpg?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 712px) 100vw, 712px\" \/><\/figure><\/div>\n\n\n<p>Open the email to check the current sensor readings.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"358\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email-2.jpg?resize=750%2C358&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"BME280 sensor readings email Micropython\" class=\"wp-image-124758\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email-2.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/01\/BME280-Sensor-Readings-Email-2.jpg?resize=300%2C143&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned the basics of sending sensor readings via email with the ESP32\/ESP8266 programmed with MicroPython firmware. As an example, we sent readings from a BME280 sensor, but you can easily modify the code to use a different sensor.<\/p>\n\n\n\n<p>The example we&#8217;ve built sends the current sensor readings when the board resets\/restarts. The idea is to add this feature to your own projects. For example, send sensor readings to your email every day, send the readings when they are above or below a certain threshold, send the readings when you click on a button&#8230; The possibilities are endless.<\/p>\n\n\n\n<p>We hope you find this tutorial useful. If you want to use a different notification method, we have a tutorial showing how to send messages to WhatsApp using MicroPython (ESP32 and ESP8266):<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/micropython-whatsapp-esp32-esp826\/\" title=\"\">MicroPython: Send Messages to WhatsApp with the ESP32\/ESP826<\/a><\/li>\n<\/ul>\n\n\n\n<p>You can check all our&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32-esp8266-micropython\/\">MicroPython projects here<\/a>.<\/p>\n\n\n\n<p>If you want to learn more about programming the ESP32 and ESP8266 boards with MicroPython, check out our eBook:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/micropython-programming-with-esp32-and-esp8266\/\"><strong>MicroPython Programming with ESP32 and ESP8266<\/strong><\/a><strong>.<\/strong><\/p>\n\n\n\n<p>Thanks for reading<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to program the ESP32 and ESP8266 boards with MicroPython to send sensor readings to your email. As an example, we&#8217;ll send temperature, humidity, and &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"MicroPython: Send Sensor Readings via email with the ESP32\/ESP826 (BME280)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/micropython-sensor-readings-email-esp32-esp826\/#more-124655\" aria-label=\"Read more about MicroPython: Send Sensor Readings via email with the ESP32\/ESP826 (BME280)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":124764,"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-124655","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\/2023\/01\/ESP32-ESP8266-Send-Email-Sensor-Readings-Micropython.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\/124655","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\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=124655"}],"version-history":[{"count":15,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/124655\/revisions"}],"predecessor-version":[{"id":126793,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/124655\/revisions\/126793"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/124764"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=124655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=124655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=124655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}