MicroPython : Envoyer les relevés de capteur ESP32/ESP826 (BME280)

MicroPython : Envoyer les relevés de capteur ESP32/ESP826 (BME280)

Dans ce didacticiel, vous apprendrez à programmer les cartes ESP32 et ESP8266 avec MicroPython pour envoyer les lectures des capteurs à votre adresse e-mail. Par exemple, nous enverrons la température, l’humidité et la pression à partir d’un capteur BME280, mais vous pouvez facilement modifier le projet pour utiliser un autre capteur.

MicroPython envoie des lectures de capteur par e-mail avec l'ESP32 ESP826 NodeMCU BME280

Allez-vous utiliser un autre capteur ? Nous avons des guides pour les capteurs suivants qui vous aideront à démarrer :

Conditions préalables

Nouveau sur MicroPython ? Vous pouvez commencer ici : Premiers pas avec MicroPython sur ESP32 et ESP8266.

Pour suivre ce tutoriel, vous avez besoin du firmware MicroPython installé dans vos cartes ESP32 ou ESP8266. Vous avez également besoin d’un IDE pour écrire et télécharger le code sur votre carte. Nous suggérons d’utiliser Thonny IDE ou uPyCraft IDE :

  • Thonny IDE :
  • uPyCraft IDE :

Ou, si vous connaissez VS Code, vous pouvez utiliser l’extension PyMakr :

Pour une comparaison entre différents IDE MicroPython, lisez : IDE MicroPython pour ESP32 et ESP8266.

En savoir plus sur MicroPython : Programmation MicroPython avec ESP32 et ESP8266 eBook.

Pièces requises

Pour ce tutoriel, vous avez besoin des pièces suivantes :

Vous pouvez utiliser les liens précédents ou accéder directement à MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

MicroPython Envoyer les releves de capteur ESP32ESP826 BME280

Module de courrier électronique

Pour envoyer facilement des e-mails avec MicroPython, nous allons utiliser un module appelé uMail. Ce module ne fait pas partie de la collection standard de bibliothèques MicroPython, nous devrons donc le télécharger séparément sur notre carte. Nous fournirons des instructions à ce sujet plus tard dans le didacticiel.

Pour vous familiariser avec l’envoi d’e-mails à l’aide de cette bibliothèque, consultez notre tutoriel :

Module BME280

Pour lire à partir du capteur BME280, nous utiliserons un module qui ne fait pas également partie des bibliothèques MicroPython standard par défaut. Nous devrons donc le télécharger sur le tableau avant de commencer à écrire le code. Le module BME280 peut être trouvé ici.

Pour un guide de démarrage pour apprendre à interfacer le BME280 avec l’ESP32/ESP8266 en utilisant MicroPython, vous pouvez lire le tutoriel suivant :

E-mail de l’expéditeur (nouveau compte)

Nous vous recommandons de créer un nouveau compte de messagerie pour envoyer les e-mails à votre adresse e-mail personnelle principale. N’utilisez pas votre e-mail personnel principal pour envoyer des e-mails via ESP32 ou ESP8266. Si quelque chose ne va pas dans votre code ou si par erreur vous faites trop de demandes, vous pouvez être banni ou voir votre compte temporairement désactivé. Nous vous recommandons d’utiliser un compte Gmail, mais d’autres fournisseurs de messagerie devraient également fonctionner.

Créer un mot de passe d’application

Vous devez créer un mot de passe d’application pour que les nouveaux appareils puissent envoyer des e-mails à l’aide de votre compte Gmail. Un mot de passe d’application est un code d’accès à 16 chiffres qui autorise une application ou un appareil moins sécurisé à accéder à votre compte Google. En savoir plus sur la connexion avec des mots de passe d’application ici.

Vous pouvez suivre ces consignes pour savoir comment créer votre mot de passe d’application.

Si vous utilisez un autre fournisseur de messagerie, vérifiez comment créer un mot de passe d’application. Vous devriez pouvoir trouver les instructions avec une recherche rapide sur Google « votre_fournisseur_email + créer un mot de passe d’application ».

Câblage du BME280

Dans ce didacticiel, nous allons créer un exemple de projet qui envoie les lectures du capteur BME280 à votre adresse e-mail. Vous devez donc câbler le capteur BME280 à votre carte. Suivez l’un des diagrammes schématiques suivants.

ESP32 avec BME280

Nous allons utiliser la communication I2C avec le module de capteur BME280. Câblez le capteur à l’ESP32 SCL par défaut (GPIO 22) et SDA (GPIO 21) broches, comme indiqué dans le diagramme schématique suivant.

Circuit de schéma de câblage de pression d'humidité de capteur ESP32 BME280

ESP8266 avec BME280

Nous allons utiliser la communication I2C avec le module de capteur BME280. Pour cela, câblez le capteur au SDA ESP8266 (GPIO 4) et SCL (GPIO 5) broches, comme indiqué dans le diagramme schématique suivant.

ESP8266 NodeMCU BME280 Capteur Température Humidité Pression Schéma de câblage Circuit

Vous n’êtes pas familier avec le BME280 avec l’ESP32/ESP8266 utilisant MicroPython ? Lisez ce tutoriel : MicroPython : BME280 avec ESP32 et ESP8266 (Pression, Température, Humidité).

Téléchargement du module uMail

Pour envoyer les e-mails, nous utiliserons le module uMail. Vous pouvez vérifier son Page Github et plusieurs exemples ici. Cette bibliothèque ne fait pas partie de la bibliothèque MicroPython standard par défaut. Vous devez donc télécharger le fichier suivant sur votre carte ESP32/ESP8266 (enregistrez-le sous le nom umail.py) avant d’utiliser la bibliothèque.

# Complete project details: https://Raspberryme.com/micropython-send-emails-esp32-esp826/
# uMail (MicroMail) for MicroPython
# Copyright (c) 2018 Shawwwn <[email protected]> https://github.com/shawwwn/uMail/blob/master/umail.py
# License: MIT
import usocket

DEFAULT_TIMEOUT = 10 # sec
LOCAL_DOMAIN = '127.0.0.1'
CMD_EHLO = 'EHLO'
CMD_STARTTLS = 'STARTTLS'
CMD_AUTH = 'AUTH'
CMD_MAIL = 'MAIL'
AUTH_PLAIN = 'PLAIN'
AUTH_LOGIN = 'LOGIN'

class SMTP:
    def cmd(self, cmd_str):
        sock = self._sock;
        sock.write('%s\r\n' % cmd_str)
        resp = []
        next = True
        while next:
            code = sock.read(3)
            next = sock.read(1) == b'-'
            resp.append(sock.readline().strip().decode())
        return int(code), resp

    def __init__(self, host, port, ssl=False, username=None, password=None):
        import ussl
        self.username = username
        addr = usocket.getaddrinfo(host, port)[0][-1]
        sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
        sock.settimeout(DEFAULT_TIMEOUT)
        sock.connect(addr)
        if ssl:
            sock = ussl.wrap_socket(sock)
        code = int(sock.read(3))
        sock.readline()
        assert code==220, 'cant connect to server %d, %s' % (code, resp)
        self._sock = sock

        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
        assert code==250, '%d' % code
        if not ssl and CMD_STARTTLS in resp:
            code, resp = self.cmd(CMD_STARTTLS)
            assert code==220, 'start tls failed %d, %s' % (code, resp)
            self._sock = ussl.wrap_socket(sock)

        if username and password:
            self.login(username, password)

    def login(self, username, password):
        self.username = username
        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
        assert code==250, '%d, %s' % (code, resp)

        auths = None
        for feature in resp:
            if feature[:4].upper() == CMD_AUTH:
                auths = feature[4:].strip('=').upper().split()
        assert auths!=None, "no auth method"

        from ubinascii import b2a_base64 as b64
        if AUTH_PLAIN in auths:
            cren = b64("\0%s\0%s" % (username, password))[:-1].decode()
            code, resp = self.cmd('%s %s %s' % (CMD_AUTH, AUTH_PLAIN, cren))
        elif AUTH_LOGIN in auths:
            code, resp = self.cmd("%s %s %s" % (CMD_AUTH, AUTH_LOGIN, b64(username)[:-1].decode()))
            assert code==334, 'wrong username %d, %s' % (code, resp)
            code, resp = self.cmd(b64(password)[:-1].decode())
        else:
            raise Exception("auth(%s) not supported " % ', '.join(auths))

        assert code==235 or code==503, 'auth error %d, %s' % (code, resp)
        return code, resp

    def to(self, addrs, mail_from=None):
        mail_from = self.username if mail_from==None else mail_from
        code, resp = self.cmd(CMD_EHLO + ' ' + LOCAL_DOMAIN)
        assert code==250, '%d' % code
        code, resp = self.cmd('MAIL FROM: <%s>' % mail_from)
        assert code==250, 'sender refused %d, %s' % (code, resp)

        if isinstance(addrs, str):
            addrs = [addrs]
        count = 0
        for addr in addrs:
            code, resp = self.cmd('RCPT TO: <%s>' % addr)
            if code!=250 and code!=251:
                print('%s refused, %s' % (addr, resp))
                count += 1
        assert count!=len(addrs), 'recipient refused, %d, %s' % (code, resp)

        code, resp = self.cmd('DATA')
        assert code==354, 'data refused, %d, %s' % (code, resp)
        return code, resp

    def write(self, content):
        self._sock.write(content)

    def send(self, content=""):
        if content:
            self.write(content)
        self._sock.write('\r\n.\r\n') # the five letter sequence marked for ending
        line = self._sock.readline()
        return (int(line[:3]), line[4:].strip().decode())

    def quit(self):
        self.cmd("QUIT")
        self._sock.close()

Afficher le code brut

Quel que soit l’IDE que vous utilisez, voici les instructions générales pour télécharger la bibliothèque uMail sur votre carte :

  1. Tout d’abord, assurez-vous que votre carte exécute le micrologiciel MicroPython – vérifiez le Rubrique Prérequis.
  2. Créez un nouveau fichier dans votre IDE avec le nom umail.py et collez-y le code précédent. Enregistrez ce fichier.
  3. Établissez une communication série avec votre carte à l’aide de votre IDE.
  4. Télécharger le umail.py fichier à votre conseil d’administration.
  5. À ce stade, la bibliothèque devrait avoir été téléchargée avec succès sur votre carte. Maintenant, vous pouvez utiliser les fonctionnalités de la bibliothèque dans votre code en important la bibliothèque : importer un e-mail.

Chargement du module BME280

Pour obtenir la température, l’humidité et la pression du capteur BME280, nous utiliserons le module suivant (nommez-le BME280.py avant de le télécharger sur votre tableau).

from machine import I2C
import time

# BME280 default address.
BME280_I2CADDR = 0x76

# Operating Modes
BME280_OSAMPLE_1 = 1
BME280_OSAMPLE_2 = 2
BME280_OSAMPLE_4 = 3
BME280_OSAMPLE_8 = 4
BME280_OSAMPLE_16 = 5

# BME280 Registers

BME280_REGISTER_DIG_T1 = 0x88  # Trimming parameter registers
BME280_REGISTER_DIG_T2 = 0x8A
BME280_REGISTER_DIG_T3 = 0x8C

BME280_REGISTER_DIG_P1 = 0x8E
BME280_REGISTER_DIG_P2 = 0x90
BME280_REGISTER_DIG_P3 = 0x92
BME280_REGISTER_DIG_P4 = 0x94
BME280_REGISTER_DIG_P5 = 0x96
BME280_REGISTER_DIG_P6 = 0x98
BME280_REGISTER_DIG_P7 = 0x9A
BME280_REGISTER_DIG_P8 = 0x9C
BME280_REGISTER_DIG_P9 = 0x9E

BME280_REGISTER_DIG_H1 = 0xA1
BME280_REGISTER_DIG_H2 = 0xE1
BME280_REGISTER_DIG_H3 = 0xE3
BME280_REGISTER_DIG_H4 = 0xE4
BME280_REGISTER_DIG_H5 = 0xE5
BME280_REGISTER_DIG_H6 = 0xE6
BME280_REGISTER_DIG_H7 = 0xE7

BME280_REGISTER_CHIPID = 0xD0
BME280_REGISTER_VERSION = 0xD1
BME280_REGISTER_SOFTRESET = 0xE0

BME280_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_CONTROL = 0xF4
BME280_REGISTER_CONFIG = 0xF5
BME280_REGISTER_PRESSURE_DATA = 0xF7
BME280_REGISTER_TEMP_DATA = 0xFA
BME280_REGISTER_HUMIDITY_DATA = 0xFD


class Device:
  """Class for communicating with an I2C device.

  Allows reading and writing 8-bit, 16-bit, and byte array values to
  registers on the device."""

  def __init__(self, address, i2c):
    """Create an instance of the I2C device at the specified address using
    the specified I2C interface object."""
    self._address = address
    self._i2c = i2c

  def writeRaw8(self, value):
    """Write an 8-bit value on the bus (without register)."""
    value = value & 0xFF
    self._i2c.writeto(self._address, value)

  def write8(self, register, value):
    """Write an 8-bit value to the specified register."""
    b=bytearray(1)
    b[0]=value & 0xFF
    self._i2c.writeto_mem(self._address, register, b)

  def write16(self, register, value):
    """Write a 16-bit value to the specified register."""
    value = value & 0xFFFF
    b=bytearray(2)
    b[0]= value & 0xFF
    b[1]= (value>>8) & 0xFF
    self.i2c.writeto_mem(self._address, register, value)

  def readRaw8(self):
    """Read an 8-bit value on the bus (without register)."""
    return int.from_bytes(self._i2c.readfrom(self._address, 1),'little') & 0xFF

  def readU8(self, register):
    """Read an unsigned byte from the specified register."""
    return int.from_bytes(
        self._i2c.readfrom_mem(self._address, register, 1),'little') & 0xFF

  def readS8(self, register):
    """Read a signed byte from the specified register."""
    result = self.readU8(register)
    if result > 127:
      result -= 256
    return result

  def readU16(self, register, little_endian=True):
    """Read an unsigned 16-bit value from the specified register, with the
    specified endianness (default little endian, or least significant byte
    first)."""
    result = int.from_bytes(
        self._i2c.readfrom_mem(self._address, register, 2),'little') & 0xFFFF
    if not little_endian:
      result = ((result << 8) & 0xFF00) + (result >> 8)
    return result

  def readS16(self, register, little_endian=True):
    """Read a signed 16-bit value from the specified register, with the
    specified endianness (default little endian, or least significant byte
    first)."""
    result = self.readU16(register, little_endian)
    if result > 32767:
      result -= 65536
    return result

  def readU16LE(self, register):
    """Read an unsigned 16-bit value from the specified register, in little
    endian byte order."""
    return self.readU16(register, little_endian=True)

  def readU16BE(self, register):
    """Read an unsigned 16-bit value from the specified register, in big
    endian byte order."""
    return self.readU16(register, little_endian=False)

  def readS16LE(self, register):
    """Read a signed 16-bit value from the specified register, in little
    endian byte order."""
    return self.readS16(register, little_endian=True)

  def readS16BE(self, register):
    """Read a signed 16-bit value from the specified register, in big
    endian byte order."""
    return self.readS16(register, little_endian=False)


class BME280:
  def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,
               **kwargs):
    # Check that mode is valid.
    if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,
                    BME280_OSAMPLE_8, BME280_OSAMPLE_16]:
        raise ValueError(
            'Unexpected mode value {0}. Set mode to one of '
            'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or '
            'BME280_ULTRAHIGHRES'.format(mode))
    self._mode = mode
    # Create I2C device.
    if i2c is None:
      raise ValueError('An I2C object is required.')
    self._device = Device(address, i2c)
    # Load calibration values.
    self._load_calibration()
    self._device.write8(BME280_REGISTER_CONTROL, 0x3F)
    self.t_fine = 0

  def _load_calibration(self):

    self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)
    self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)
    self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)

    self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)
    self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)
    self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)
    self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)
    self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)
    self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)
    self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)
    self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)
    self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)

    self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)
    self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)
    self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)
    self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)

    h4 = self._device.readS8(BME280_REGISTER_DIG_H4)
    h4 = (h4 << 24) >> 20
    self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) & 0x0F)

    h5 = self._device.readS8(BME280_REGISTER_DIG_H6)
    h5 = (h5 << 24) >> 20
    self.dig_H5 = h5 | (
        self._device.readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F)

  def read_raw_temp(self):
    """Reads the raw (uncompensated) temperature from the sensor."""
    meas = self._mode
    self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)
    meas = self._mode << 5 | self._mode << 2 | 1
    self._device.write8(BME280_REGISTER_CONTROL, meas)
    sleep_time = 1250 + 2300 * (1 << self._mode)

    sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
    sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
    time.sleep_us(sleep_time)  # Wait the required time
    msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)
    lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)
    xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)
    raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
    return raw

  def read_raw_pressure(self):
    """Reads the raw (uncompensated) pressure level from the sensor."""
    """Assumes that the temperature has already been read """
    """i.e. that enough delay has been provided"""
    msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)
    lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)
    xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)
    raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
    return raw

  def read_raw_humidity(self):
    """Assumes that the temperature has already been read """
    """i.e. that enough delay has been provided"""
    msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)
    lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)
    raw = (msb << 8) | lsb
    return raw

  def read_temperature(self):
    """Get the compensated temperature in 0.01 of a degree celsius."""
    adc = self.read_raw_temp()
    var1 = ((adc >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
    var2 = ((
        (((adc >> 4) - self.dig_T1) * ((adc >> 4) - self.dig_T1)) >> 12) *
        self.dig_T3) >> 14
    self.t_fine = var1 + var2
    return (self.t_fine * 5 + 128) >> 8

  def read_pressure(self):
    """Gets the compensated pressure in Pascals."""
    adc = self.read_raw_pressure()
    var1 = self.t_fine - 128000
    var2 = var1 * var1 * self.dig_P6
    var2 = var2 + ((var1 * self.dig_P5) << 17)
    var2 = var2 + (self.dig_P4 << 35)
    var1 = (((var1 * var1 * self.dig_P3) >> 8) +
            ((var1 * self.dig_P2) >> 12))
    var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
    if var1 == 0:
      return 0
    p = 1048576 - adc
    p = (((p << 31) - var2) * 3125) // var1
    var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
    var2 = (self.dig_P8 * p) >> 19
    return ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)

  def read_humidity(self):
    adc = self.read_raw_humidity()
    # print 'Raw humidity = {0:d}'.format (adc)
    h = self.t_fine - 76800
    h = (((((adc << 14) - (self.dig_H4 << 20) - (self.dig_H5 * h)) +
         16384) >> 15) * (((((((h * self.dig_H6) >> 10) * (((h *
                          self.dig_H3) >> 11) + 32768)) >> 10) + 2097152) *
                          self.dig_H2 + 8192) >> 14))
    h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
    h = 0 if h < 0 else h
    h = 419430400 if h > 419430400 else h
    return h >> 12

  @property
  def temperature(self):
    "Return the temperature in degrees."
    t = self.read_temperature()
    ti = t // 100
    td = t - ti * 100
    return "{}.{:02d}C".format(ti, td)

  @property
  def pressure(self):
    "Return the temperature in hPa."
    p = self.read_pressure() // 256
    pi = p // 100
    pd = p - pi * 100
    return "{}.{:02d}hPa".format(pi, pd)

  @property
  def humidity(self):
    "Return the humidity in percent."
    h = self.read_humidity()
    hi = h // 1024
    hd = h * 100 // 1024 - hi * 100
    return "{}.{:02d}%".format(hi, hd)

Afficher le code brut

Quel que soit l’IDE que vous utilisez, voici les instructions générales pour télécharger la bibliothèque BME280 sur votre carte :

  1. Tout d’abord, assurez-vous que votre carte exécute le micrologiciel MicroPython – vérifiez le Rubrique Prérequis.
  2. Créez un nouveau fichier dans votre IDE avec le nom BME280.py et collez-y le code précédent. Enregistrez ce fichier.
  3. Établissez une communication série avec votre carte à l’aide de votre IDE.
  4. Télécharger le BME280.py fichier à votre conseil d’administration.
  5. À ce stade, la bibliothèque devrait avoir été téléchargée avec succès sur votre carte. Maintenant, vous pouvez utiliser les fonctionnalités de la bibliothèque dans votre code en important la bibliothèque : importer BME280.

Envoi de lectures de capteurs par e-mail – MicroPython – Code

Maintenant, vous devriez avoir téléchargé le umail.pyet BME280.py fichiers sur votre carte pour pouvoir envoyer des e-mails et lire à partir du capteur BME280.

Le script suivant envoie un nouvel e-mail avec les lectures actuelles du capteur lorsque la carte ESP32/ESP8266 démarre/réinitialise pour la première fois.

# Complete project details: https://Raspberryme.com/micropython-sensor-readings-email-esp32-esp826/
import umail # Micropython lib to send emails: https://github.com/shawwwn/uMail
import network
import BME280
from machine import Pin, SoftI2C

# Your network credentials
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

# Email details
sender_email="REPLACE_WITH_THE_SENDER_EMAIL"
sender_name="ESP32" #sender name
sender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'
recipient_email="REPLACE_WITH_THE_RECIPIENT_EMAIL"
email_subject="BME280 Sensor Readings"

# BME280 pin assignment - ESP32
i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)
# BME280 pin assignment - ESP8266
#i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000)
bme = BME280.BME280(i2c=i2c)

def read_bme_sensor():
  try:
    temp = str(bme.temperature[:-1]) + " ºC"
    #uncomment for temperature in Fahrenheit
    #temp = str((bme.read_temperature()/100) * (9/5) + 32) + " 潞F"
    hum = str(bme.humidity[:-1]) + " %"
    pres = str(bme.pressure[:-3]) + " hPa"

    return temp, hum, pres
    #else:
    #  return('Invalid sensor readings.')
  except OSError as e:
    return('Failed to read sensor.')
  
def connect_wifi(ssid, password):
  #Connect to your network
  station = network.WLAN(network.STA_IF)
  station.active(True)
  station.connect(ssid, password)
  while station.isconnected() == False:
    pass
  print('Connection successful')
  print(station.ifconfig())
    
# Connect to your network
connect_wifi(ssid, password)

# Get sensor readings
temp, hum, pres = read_bme_sensor()
print(temp)
print(hum)
print(pres)

# Send the email
smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port
smtp.login(sender_email, sender_app_password)
smtp.to(recipient_email)
smtp.write("From:" + sender_name + "<"+ sender_email+">\n")
smtp.write("Subject:" + email_subject + "\n")
smtp.write("Temperature " + temp + "\n")
smtp.write("Humidity " + hum + "\n")
smtp.write("Pressure " + pres + "\n")
smtp.send()
smtp.quit()

Afficher le code brut

Vous devez insérer vos propres informations dans le code avant de télécharger le code sur le tableau : SSID et mot de passe, e-mail de l’expéditeur, nom de l’expéditeur et mot de passe d’application correspondant, e-mail du destinataire et objet de l’e-mail.

Après avoir inséré toutes vos coordonnées, vous pouvez télécharger le code sur votre tableau. Le fichier avec le code doit être nommé main.pysinon, ça ne marchera pas.

Comment fonctionne le code

Continuez à lire pour savoir comment le code fonctionne, ou passez à la Manifestation section.

Y compris les bibliothèques

Tout d’abord, incluez les bibliothèques requises. Le umail bibliothèque, que nous avons chargée précédemment sur le tableau, afin que nous puissions envoyer des e-mails, et la réseau bibliothèque afin que nous puissions définir l’ESP32/ESP8266 comme une station wi-fi pour pouvoir se connecter à Internet (réseau local). De plus, vous devez importer le BME280 module à lire à partir du capteur BME280, et le Broche et I2C cours de la machine module pour établir une communication I2C avec le capteur.

import umail # Micropython lib to send emails: https://github.com/shawwwn/uMail
import network
import BME280
from machine import Pin, SoftI2C

Informations d’identification réseau

Insérez vos informations d’identification réseau, SSID et mot de passe dans les variables suivantes afin que votre carte puisse se connecter à Internet :

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

Détails de l’e-mail

Insérez les détails de l’e-mail : e-mail de l’expéditeur, nom de l’expéditeur et mot de passe d’application correspondant. Vous devez vraiment créer un mot de passe d’application – l’utilisation du mot de passe de messagerie standard ne fonctionnera pas, vérifiez ces instructions.

# Email details
sender_email="REPLACE_WITH_THE_SENDER_EMAIL"
sender_name="ESP32" #sender name
sender_app_password = 'REPLACE_WITH_THE_SENDER_EMAIL_APP_PASSWORD'

Insérez l’e-mail du destinataire sur le Destinataire E-mail variable:

recipient_email="REPLACE_WITH_THE_RECIPIENT_EMAIL"

BME280

L’objet de l’e-mail est défini sur Lectures du capteur BME280mais vous pouvez le modifier sur le Sujet du courriel variable.

email_subject="BME280 Sensor Readings"

Créez un objet i2c en utilisant les broches I2C de la carte. L’ESP32 utilise GPIO 22 et GPIO 21 comme broches I2C.

i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000)

Si vous utilisez une carte ESP8266, vous devez utiliser GPIO 4 et GPIO 5 à la place.

i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000)

Si vous utilisez une carte avec différentes broches I2C, assurez-vous de modifier cette ligne précédente.

Maintenant que nous avons un i2c objet, nous pouvons créer un BME280 objet (dans ce cas appelé bme) sur ces broches.

bme = BME280.BME280(i2c=i2c)

Lecture BME280 : Température, humidité et pression

Pour lire à partir du capteur BME280, nous avons créé une fonction appelée read_bme_sensor() qui renvoie la température, l’humidité et la pression sous forme de chaînes avec les unités correspondantes, ce qui est le format idéal à utiliser dans le corps de l’e-mail.

def read_bme_sensor():
  try:
    temp = str(bme.temperature[:-1]) + " ºC"
    #uncomment for temperature in Fahrenheit
    #temp = str((bme.read_temperature()/100) * (9/5) + 32) + " ºF"
    hum = str(bme.humidity[:-1]) + " %"
    pres = str(bme.pressure[:-3]) + " hPa"

    return temp, hum, pres
    #else:
    #  return('Invalid sensor readings.')
  except OSError as e:
    return('Failed to read sensor.')

Par défaut, la fonction renvoie la température en degrés Celsius. Si vous souhaitez obtenir la température en Fahrenheit, il vous suffit de décommenter la ligne suivante :

#temp = str((bme.read_temperature()/100) * (9/5) + 32) + " ºF"

Connexion au Wi-Fi

Pour connecter la carte au Wi-Fi, nous avons créé une fonction appelée connect_wifi() qui accepte comme arguments le SSID et le mot de passe du réseau auquel vous souhaitez vous connecter. Vous devriez appeler cette fonction plus tard pour connecter réellement la carte ESP à Internet.

def connect_wifi(ssid, password):
  #Connect to your network
  station = network.WLAN(network.STA_IF)
  station.active(True)
  station.connect(ssid, password)
  while station.isconnected() == False:
    pass
  print('Connection successful')
  print(station.ifconfig())

Avant d’envoyer l’e-mail, nous devons connecter l’ESP32/ESP8266 à Internet, alors appelez le connect_wifi() fonction (passez en arguments le ssid et le mot de passe).

# Connect to your network
connect_wifi(ssid, password)

Obtenir de nouvelles lectures

Pour obtenir les lectures du capteur dans le format que nous voulons, nous avons juste besoin d’appeler le read_bme_sensor() fonction que nous avons créée précédemment. La température, l’humidité et la pression sont enregistrées sur le temp, humet prés variables. Ce sont des variables de chaîne qui incluent déjà les unités (ºC, % et hPa). Les lignes suivantes, obtenez les dernières lectures et imprimez-les sur la coque.

# Get sensor readings
temp, hum, pres = read_bme_sensor()
print(temp)
print(hum)
print(pres)

Envoi de l’e-mail

Maintenant, nous pouvons enfin commencer à préparer et à envoyer l’e-mail.

Commencez par créer un client SMTP à l’aide des paramètres SMTP de votre fournisseur de messagerie appelé smtp. Ici, nous utilisons un compte Gmail. Modifiez les paramètres si vous utilisez un autre fournisseur de messagerie—définissez le serveur, le port et si SSL est requis ou non.

smtp = umail.SMTP('smtp.gmail.com', 465, ssl=True) # Gmail's SSL port

Ensuite, connectez-vous à votre compte en utilisant le connexion() méthode sur la smtp client : transmettez comme arguments l’e-mail et le mot de passe d’application correspondant.

smtp.login(sender_email, sender_app_password)

Définissez le destinataire à l’aide de la pour() et passez l’email du destinataire en argument :

smtp.to(recipient_email)

Ensuite, utilisez le écrire() méthode pour écrire l’e-mail. Vous pouvez utiliser cette méthode comme suit pour définir le nom de l’expéditeur.

smtp.write("From:" + sender_name + "<"+ sender_email+">\n")

Et vous pouvez utiliser la ligne suivante pour définir l’objet de l’e-mail.

smtp.write("Subject:" + email_subject + "\n")

Enfin, vous pouvez réellement écrire le contenu de votre e-mail. Nous envoyons simplement les valeurs de température, d’humidité et de pression dans le corps de l’e-mail, mais vous pouvez ajouter plus de texte ou même du code HTML pour formater le corps de l’e-mail. Le écrire() méthode envoie l’e-mail au serveur SMTP.

smtp.write("Temperature " + temp + "\n")
smtp.write("Humidity " + hum + "\n")
smtp.write("Pressure " + pres + "\n")

Si vous devez envoyer une longue chaîne comme corps de l’e-mail, divisez l’e-mail en petits morceaux et envoyez chaque morceau à l’aide de la écrire() méthode-voir la documentation de la bibliothèque uMail.

Enfin, utilisez le envoyer() méthode pour que le serveur SMTP envoie l’e-mail au destinataire.

smtp.send()

A la fin, fermez la connexion avec le serveur en utilisant le arrêter() méthode.

smtp.quit()

Manifestation

Après avoir téléchargé le umailet le BME280 modules, et les main.py script sur votre carte, exécutez le code ou réinitialisez/redémarrez votre carte. Vous devriez obtenir un message similaire dans le shell indiquant que votre carte s’est connectée avec succès à Internet, et les lectures actuelles du capteur.

Lectures de capteurs via e-mail micropython shell

Au bout d’un moment, vous devriez recevoir un nouvel e-mail sur le compte de messagerie du destinataire.

e-mail envoyé depuis EPS32 ESP8266 NodeMCU à l'aide de la boîte de réception MicroPython

Ouvrez l’e-mail pour vérifier les lectures actuelles du capteur.

Courriel des lectures du capteur BME280 Micropython

Conclusion

Dans ce didacticiel, vous avez appris les bases de l’envoi de lectures de capteurs par e-mail avec l’ESP32/ESP8266 programmé avec le micrologiciel MicroPython. À titre d’exemple, nous avons envoyé des lectures à partir d’un capteur BME280, mais vous pouvez facilement modifier le code pour utiliser un autre capteur.

L’exemple que nous avons construit envoie les lectures actuelles du capteur lorsque la carte se réinitialise/redémarre. L’idée est d’ajouter cette fonctionnalité à vos propres projets. Par exemple, envoyer chaque jour les relevés des capteurs sur votre messagerie, envoyer les relevés lorsqu’ils sont au-dessus ou en dessous d’un certain seuil, envoyer les relevés lorsque vous cliquez sur un bouton… Les possibilités sont infinies.

Nous espérons que vous trouverez ce tutoriel utile. Si vous souhaitez utiliser une méthode de notification différente, nous avons un tutoriel montrant comment envoyer des messages à WhatsApp en utilisant MicroPython (ESP32 et ESP8266) :

Vous pouvez consulter tous nos projets MicroPython ici.

Si vous souhaitez en savoir plus sur la programmation des cartes ESP32 et ESP8266 avec MicroPython, consultez notre eBook : Programmation MicroPython avec ESP32 et ESP8266.

Merci d’avoir lu

Plongez dans l’histoire de Raspberry Pi avec cette vidéo :

YouTube video