MicroPython: BME280 с ESP32 и ESP8266 (давление, температура, влажность)

В этом руководстве вы узнаете, как использовать модуль датчика BME280 с ESP32 и ESP8266 для получения показаний давления, температуры и влажности, используя прошивку MicroPython. Мы создадим простой пример для ознакомления с датчиком и веб-сервер для отображения показаний датчика.

MicroPython BME280 с ESP32 и ESP8266 Температура, Влажность и Давление

Необходимые условия

Для выполнения этого руководства вам необходимо установить прошивку MicroPython на ваши платы ESP32 или ESP8266. Вам также понадобится IDE для написания и загрузки кода на плату. Мы рекомендуем использовать Thonny IDE или uPyCraft IDE:

Подробнее о MicroPython: MicroPython Programming with ESP32 and ESP8266 eBook.

Вас также могут заинтересовать другие руководства по BME280:

Знакомство с модулем датчика BME280

Модуль датчика BME280 измеряет барометрическое давление, температуру и влажность. Поскольку давление изменяется с высотой, вы также можете оценить высоту над уровнем моря. Существует несколько версий этого модуля датчика, но мы используем ту, что показана на рисунке ниже.

Датчик BME280 температура, влажность и давление

Этот датчик взаимодействует по протоколу I2C, поэтому подключение очень простое. Вы можете использовать стандартные выводы I2C на ESP32 или ESP8266, как показано в следующей таблице:

BME280

ESP32

ESP8266

Vin

3.3V

3.3V

GND

GND

GND

SCL

GPIO 22

GPIO 5 (D1)

SDA

GPIO 21

GPIO 4 (D2)

Необходимые компоненты

MicroPython BME280 с ESP32 и ESP8266 необходимые компоненты

Для этого проекта вам нужно подключить модуль датчика BME280 к выводам I2C ESP32 или ESP8266. Вот список компонентов, необходимых для этого руководства:

Схема подключения – ESP32

Используйте следующую схему подключения, если вы используете плату ESP32:

Схема подключения ESP32 BME280

Рекомендуемое чтение: Справочник по выводам ESP32

Схема подключения – ESP8266

Используйте следующую схему подключения, если вы используете плату ESP8266:

Схема подключения ESP8266 BME280

Рекомендуемое чтение: Справочник по выводам ESP8266

Библиотека BME280 для MicroPython

Библиотека для чтения данных с датчика BME280 не входит в стандартную библиотеку MicroPython по умолчанию. Поэтому вам нужно загрузить следующую библиотеку на вашу плату ESP32/ESP8266 (сохраните её с именем BME280.py).

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)

Посмотреть исходный код

Следуйте инструкциям для используемой вами IDE:

    1. Загрузка библиотеки BME280 с помощью uPyCraft IDE

    1. Загрузка библиотеки BME280 с помощью Thonny IDE

A. Загрузка библиотеки BME280 с помощью uPyCraft IDE

В этом разделе показано, как загрузить библиотеку с помощью uPyCraft IDE. Если вы используете Thonny IDE, прочитайте следующий раздел.

1. Создайте новый файл, нажав кнопку New File (1).

2. Скопируйте код библиотеки BME280 в этот файл. Код библиотеки BME280 можно найти здесь.

3. После копирования кода сохраните файл, нажав кнопку Save (2).

Установка библиотеки BME280 MicroPython ESP32 ESP8266 uPyCraft IDE шаг 1

4. Назовите этот новый файл «BME280.py» и нажмите ok.

Установка библиотеки BME280 MicroPython ESP32 ESP8266 uPyCraft IDE шаг 2

5. Нажмите кнопку Download and Run.

Установка библиотеки BME280 MicroPython ESP32 ESP8266 uPyCraft IDE шаг 3

Файл должен быть сохранён в папке устройства с именем «BME280.py», как показано на следующем рисунке.

Установка библиотеки BME280 MicroPython ESP32 ESP8266 uPyCraft IDE шаг 4

Теперь вы можете использовать функции библиотеки в своём коде, импортировав библиотеку.

B. Загрузка библиотеки BME280 с помощью Thonny IDE

Если вы используете Thonny IDE, выполните следующие шаги:

1. Скопируйте код библиотеки в новый файл. Код библиотеки BME280 можно найти здесь.

2. Перейдите в File > Save as…

Thonny IDE ESP32 ESP8266 MicroPython Сохранить файл библиотеки на устройство

3. Выберите сохранение на «MicroPython device»:

Thonny IDE ESP32 ESP8266 MicroPython Выбрать устройство

4. Назовите ваш файл BME280.py и нажмите кнопку OK:

Библиотека BME280 новый файл MicroPython Thonny IDE

Вот и всё. Библиотека загружена на вашу плату. Чтобы убедиться, что она была успешно загружена, перейдите в File > Save as… и выберите MicroPython device. Ваш файл должен быть указан там:

Библиотека BME280 файл MicroPython создан Thonny IDE

После загрузки библиотеки на вашу плату вы можете использовать функции библиотеки в своём коде, импортировав библиотеку.

Код – Давление, температура и влажность BME280

После загрузки библиотеки на ESP32 или ESP8266 скопируйте следующий код в файл main.py или boot.py. Он просто выводит температуру, влажность и давление в консоль каждые 5 секунд.

# Complete project details at https://RandomNerdTutorials.com

from machine import Pin, I2C
from time import sleep
import BME280

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

while True:
  bme = BME280.BME280(i2c=i2c)
  temp = bme.temperature
  hum = bme.humidity
  pres = bme.pressure
  # uncomment for temperature in Fahrenheit
  #temp = (bme.read_temperature()/100) * (9/5) + 32
  #temp = str(round(temp, 2)) + 'F'
  print('Temperature: ', temp)
  print('Humidity: ', hum)
  print('Pressure: ', pres)

  sleep(5)

Посмотреть исходный код

Как работает код

Сначала вам нужно импортировать необходимые библиотеки, включая модуль BME280, который вы импортировали ранее.

from machine import Pin, I2C
from time import sleep
import BME280

Установите выводы I2C. В данном случае мы используем стандартные выводы I2C. Если вы используете ESP32, установите выводы следующим образом:

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

Если вы используете ESP8266, закомментируйте предыдущую строку и раскомментируйте следующую, чтобы получилось:

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

В цикле while создайте объект BME280 с именем bme с определёнными ранее выводами I2C:

bme = BME280.BME280(i2c=i2c)

Чтение температуры, влажности и давления выполняется простым обращением к методам temperature, humidity и pressure объекта bme.

temp = bme.temperature
hum = bme.humidity
pres = bme.pressure

Наконец, выведите показания в консоль:

print('Temperature: ', temp)
print('Humidity: ', hum)
print('Pressure: ', pres)

В конце мы добавляем задержку в 5 секунд:

sleep(5)

Демонстрация

После загрузки кода на вашу плату нажмите кнопку RST для запуска кода. Новые показания датчика BME280 должны отображаться каждые 5 секунд.

BME280 MicroPython ESP32 ESP8266 вывод показаний в Python Shell

Отображение показаний BME280 на веб-сервере

Теперь, когда вы знаете, как получать давление, температуру и влажность от датчика BME280, мы отобразим показания датчика на веб-сервере, к которому вы можете получить доступ в вашей локальной сети.

Отображение показаний BME280 на веб-сервере с ESP32 или ESP8266

Для этого примера вам понадобятся три файла:

  • BME280.py: это файл, который содержит все методы для работы с датчиком BME280. Это файл, который вы загрузили ранее.

  • boot.py: запускается при старте устройства и настраивает различные параметры конфигурации, такие как сетевые учётные данные, импорт библиотек, настройка выводов и т.д.

  • main.py: это основной скрипт, в котором мы обрабатываем веб-сервер. Он выполняется сразу после boot.py.

Примечание

Хорошей практикой является включение файлов boot.py и main.py. Однако, если вы предпочитаете, вы можете включить весь код в файл main.py.

boot.py

Создайте новый файл в вашей IDE с именем boot.py и скопируйте следующий код.

# Complete project details at https://RandomNerdTutorials.com

try:
  import usocket as socket
except:
  import socket

from time import sleep

from machine import Pin, I2C
import network

import esp
esp.osdebug(None)

import gc
gc.collect()

import BME280

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

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

station = network.WLAN(network.STA_IF)

station.active(True)
station.connect(ssid, password)

while station.isconnected() == False:
  pass

print('Connection successful')
print(station.ifconfig())

Посмотреть исходный код

Этот файл импортирует необходимые библиотеки, определяет выводы I2C для подключения к датчику и подключается к вашей сети.

В коде мы используем выводы I2C ESP32:

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

Если вы используете ESP8266, закомментируйте предыдущую строку и раскомментируйте следующую:

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

Затем введите ваши сетевые учётные данные в следующие переменные:

ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'

main.py

В файле main.py мы создадим веб-сервер и обработаем запросы. Скопируйте следующий код в ваш файл main.py.

# Complete project details at https://RandomNerdTutorials.com

def web_page():
  bme = BME280.BME280(i2c=i2c)

  html = """<html><head><meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"><style>body { text-align: center; font-family: "Trebuchet MS", Arial;}
  table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }
  th { padding: 12px; background-color: #0043af; color: white; }
  tr { border: 1px solid #ddd; padding: 12px; }
  tr:hover { background-color: #bcbcbc; }
  td { border: none; padding: 12px; }
  .sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px;
  </style></head><body><h1>ESP with BME280</h1>
  <table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>
  <tr><td>Temp. Celsius</td><td><span class="sensor">""" + str(bme.temperature) + """</span></td></tr>
  <tr><td>Temp. Fahrenheit</td><td><span class="sensor">""" + str(round((bme.read_temperature()/100.0) * (9/5) + 32, 2))  + """F</span></td></tr>
  <tr><td>Pressure</td><td><span class="sensor">""" + str(bme.pressure) + """</span></td></tr>
  <tr><td>Humidity</td><td><span class="sensor">""" + str(bme.humidity) + """</span></td></tr></body></html>"""
  return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)

while True:
  try:
    if gc.mem_free() < 102000:
      gc.collect()
    conn, addr = s.accept()
    conn.settimeout(3.0)
    print('Got a connection from %s' % str(addr))
    request = conn.recv(1024)
    conn.settimeout(None)
    request = str(request)
    print('Content = %s' % request)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()
  except OSError as e:
    conn.close()
    print('Connection closed')

Посмотреть исходный код

Этот код создаёт сокет-сервер, который отправляет HTML-страницу с последними показаниями датчика, когда получает запрос по IP-адресу ESP32 или ESP8266.

По сути, у нас есть функция web_page(), которая возвращает HTML для построения веб-страницы с последними показаниями датчика. Этот HTML-текст создаёт таблицу для отображения показаний:

html = """<html><head><meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"><style>body { text-align: center; font-family: "Trebuchet MS", Arial;}
  table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }
  th { padding: 12px; background-color: #0043af; color: white; }
  tr { border: 1px solid #ddd; padding: 12px; }
  tr:hover { background-color: #bcbcbc; }
  td { border: none; padding: 12px; }
  .sensor { color:white; font-weight: bold; background-color: #bcbcbc; padding: 1px;
  </style></head><body><h1>ESP with BME280</h1>
  <table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>
  <tr><td>Temp. Celsius</td><td><span class="sensor">""" + str(bme.temperature) + """</span></td></tr>
  <tr><td>Temp. Fahrenheit</td><td><span class="sensor">""" + str(round((bme.read_temperature()/100.0) * (9/5) + 32, 2)) + """F</span></td></tr>
  <tr><td>Pressure</td><td><span class="sensor">""" + str(bme.pressure) + """</span></td></tr>
  <tr><td>Humidity</td><td><span class="sensor">""" + str(bme.humidity) + """</span></td></tr>
  </body></html>"""

Затем мы создаём сокет-сервер, который отправляет HTML при получении запроса. HTML-текст сохраняется в переменной response:

response = web_page()

И отправляется клиенту:

conn.sendall(response)

Мы подробно объясняли работу таких веб-серверов в предыдущих руководствах. Если вы хотите узнать, как это работает, вы можете прочитать следующие статьи:

Демонстрация веб-сервера

Загрузите все предыдущие файлы на вашу плату ESP32 или ESP8266 в следующем порядке:

  1. BME280.py

  2. boot.py

  3. main.py

Если вы не знаете, как загружать код, вы можете прочитать наши руководства по началу работы с uPyCraft IDE или Thonny IDE:

После загрузки кода на Serial Monitor должен отобразиться IP-адрес вашей ESP32 или ESP8266.

MicroPython IP адрес

Откройте веб-браузер в вашей локальной сети и введите IP-адрес вашего ESP (в нашем примере IP – http://192.168.1.71). Вы должны увидеть страницу с последними показаниями датчика, как показано на следующем рисунке.

BME280 Веб-сервер MicroPython с ESP8266 или ESP32

Автообновление веб-страницы

С предоставленным в этом проекте скриптом веб-сервера вам нужно обновлять веб-страницу для просмотра последних показаний. Если вы добавите следующий мета-тег внутрь HTML-тегов <head></head>, ваша веб-страница будет автоматически обновляться каждые 10 секунд:

<meta http-equiv="refresh" content="10">

Заключение

Надеемся, это руководство было для вас полезным. У нас есть другие проекты и руководства с MicroPython, которые могут вам понравиться:

Если вы хотите узнать больше о программировании плат ESP32 и ESP8266 с MicroPython, получите доступ к нашей электронной книге: MicroPython Programming with ESP32 and ESP8266.