Blog Archive

Arduino Indonesia. Gambar tema oleh Storman. Diberdayakan oleh Blogger.

Supported by Electronics 3 in 1

1. Jasa pencetakan PCB single layer dengan harga paling murah.

(Metode Pembuatan dengan Transfer Toner)
>PCB design sendiri (siap cetak) : Rp.150,-/Cm2
>PCB design dari kami : Rp.250,-/Cm2

(Metode Sablon Full Masking dan Silk Screen minimal pemesanan 100 Pcs)
>PCB design sendiri (siap cetak) : Rp.200,-/Cm2
>PCB design dari kami : Rp.250,-/Cm2

2. Jasa perancangan, perakitan, dan pembuatan trainer pembelajaran elektronika untuk SMK dan Mahasiswa.

3. Jasa perancangan, perakitan, dan pembuatan berbagai macam kontroller, sensor, aktuator, dan tranduser.
>Design Rangkaian / Sistem Elektronika
>Design Rangkaian / Sistem Instrumentasi
>Design Rangkaian / Sistem Kendali
>Kerjasama Riset (data atau peralatan)
>Kerjasama Produksi Produk-Produk KIT Elektronika
>Produksi Instrumentasi Elektronika

4. Jasa Pembuatan Proyek, Tugas Akhir, Tugas Laboratorium, PKM, Karya Ilmiah, SKRIPSI, dll

Like My Facebook

Popular Posts

Senin, 29 Desember 2025

Tutorial MicroPython ESP32 dan ESP8266 - Sensor BME680 untuk Monitoring Suhu, Kelembaban, Tekanan & Gas

Pada artikel ini, Anda akan belajar menggunakan modul sensor BME680 dengan ESP32 dan ESP8266 untuk mendapatkan pembacaan suhu, kelembaban, tekanan, dan gas (kualitas udara) menggunakan firmware MicroPython. Kami akan membangun contoh sederhana untuk membiasakan Anda dengan sensor, serta sebuah web server untuk menampilkan data sensor Anda.

Mengenal Modul Sensor Lingkungan BME680

BME680 adalah sensor lingkungan yang menggabungkan sensor gas, tekanan, kelembaban, dan suhu. Sensor gasnya dapat mendeteksi berbagai jenis gas, seperti senyawa organik yang mudah menguap (Volatile Organic Compounds/VOC). Oleh karena itu, BME680 cocok digunakan untuk pengendalian kualitas udara dalam ruangan.

Pengukuran BME680

BME680 adalah sensor digital 4-in-1 yang mengukur:

1. Suhu

2. Kelembaban

3. Tekanan barometrik

4. Gas: Senyawa Organik yang Mudah Menguap (Volatile Organic Compounds/VOC) seperti etanol dan karbon monoksida

Sensor Gas

BME680 mengandung sensor MOX (Metal-oxide) yang mendeteksi VOC di udara. Sensor ini memberikan gambaran kualitatif dari total VOC/kontaminan di udara sekitar – ia tidak spesifik untuk molekul gas tertentu.

 

Sensor MOX terdiri dari permukaan metal-oxide, chip pengindera untuk mengukur perubahan konduktivitas, dan sebuah pemanas. Ia mendeteksi VOC melalui penyerapan molekul oksigen pada lapisan sensitifnya. BME680 bereaksi terhadap sebagian besar VOC yang mencemari udara dalam ruangan (kecuali CO2).

 

Ketika sensor bersentuhan dengan gas pereduksi, molekul oksigen bereaksi dan meningkatkan konduktivitas di seluruh permukaan. Sebagai sinyal mentah (raw), BME680 mengeluarkan nilai resistansi. Nilai-nilai ini berubah karena variasi konsentrasi VOC:


- Konsentrasi VOC lebih tinggi → Resistansi lebih rendah

- Konsentrasi VOC lebih rendah → Resistansi lebih tinggi

Reaksi yang terjadi pada permukaan sensor (dan dengan demikian, resistansinya) juga dipengaruhi oleh parameter lain selain konsentrasi VOC, seperti suhu dan kelembaban.

Informasi Penting tentang Sensor Gas

Sensor gas memberikan gambaran kualitatif tentang gas VOC di udara sekitar. Jadi, Anda dapat melihat tren, membandingkan hasil, dan menilai apakah kualitas udara membaik atau memburuk. Untuk mendapatkan pengukuran yang presisi, Anda perlu mengkalibrasi sensor terhadap sumber yang diketahui dan membuat kurva kalibrasi.

 

Saat pertama kali mendapatkan sensor, disarankan untuk menjalankannya selama 48 jam sebelum mulai mengumpulkan data "nyata". Setelah itu, juga disarankan untuk menjalankan sensor selama 30 menit sebelum mengambil pembacaan gas.

Akurasi BME680

Berikut adalah akurasi untuk sensor suhu, kelembaban, dan tekanan pada BME680:

Rentang Operasional BME680

Tabel berikut menunjukkan rentang operasional untuk sensor suhu, kelembaban, dan tekanan pada BME680.

Pinout BME680

Berikut adalah konfigurasi pin (pinout) BME680:

Antarmuka BME680

BME680 mendukung antarmuka komunikasi I2C dan SPI.



BME680 dengan Antarmuka I2C

Sensor ini berkomunikasi menggunakan protokol I2C, sehingga koneksi kabelnya sangat sederhana. Anda dapat menggunakan pin I2C default pada ESP32 atau ESP8266.

Komponen yang Diperlukan

Untuk proyek ini, Anda perlu menghubungkan modul sensor BME680 ke pin I2C ESP32 atau ESP8266. Berikut adalah daftar komponen yang diperlukan untuk tutorial ini:

- Modul sensor BME680

- ESP32 atau ESP8266

- Papan breadboard

- Kabel jumper

Skematik – ESP32

Ikuti diagram skematik berikut jika Anda menggunakan papan ESP32:



Skematik – ESP8266

Ikuti diagram skematik berikut jika Anda menggunakan papan ESP8266:


Library MicroPython untuk BME680

Pustaka untuk membaca data dari sensor BME680 tidak termasuk dalam pustaka standar MicroPython secara default. Oleh karena itu, Anda perlu mengunggah pustaka berikut ke papan ESP32/ESP8266 Anda (simpan dengan nama `bme680.py`).

 

# Original source: https://github.com/adafruit/Adafruit_CircuitPython_BME680/blob/master/adafruit_bme680.py

import time

import math

from micropython import const

from ubinascii import hexlify as hex

try:

  import struct

except ImportError:

  import ustruct as struct

_BME680_CHIPID = const(0x61)

_BME680_REG_CHIPID = const(0xD0)

_BME680_BME680_COEFF_ADDR1 = const(0x89)

_BME680_BME680_COEFF_ADDR2 = const(0xE1)

_BME680_BME680_RES_HEAT_0 = const(0x5A)

_BME680_BME680_GAS_WAIT_0 = const(0x64)

_BME680_REG_SOFTRESET = const(0xE0)

_BME680_REG_CTRL_GAS = const(0x71)

_BME680_REG_CTRL_HUM = const(0x72)

_BME280_REG_STATUS = const(0xF3)

_BME680_REG_CTRL_MEAS = const(0x74)

_BME680_REG_CONFIG = const(0x75)

_BME680_REG_PAGE_SELECT = const(0x73)

_BME680_REG_MEAS_STATUS = const(0x1D)

_BME680_REG_PDATA = const(0x1F)

_BME680_REG_TDATA = const(0x22)

_BME680_REG_HDATA = const(0x25)

_BME680_SAMPLERATES = (0, 1, 2, 4, 8, 16)

_BME680_FILTERSIZES = (0, 1, 3, 7, 15, 31, 63, 127)

_BME680_RUNGAS = const(0x10)

_LOOKUP_TABLE_1 = (2147483647.0, 2147483647.0, 2147483647.0, 2147483647.0, 2147483647.0,

  2126008810.0, 2147483647.0, 2130303777.0, 2147483647.0, 2147483647.0,

  2143188679.0, 2136746228.0, 2147483647.0, 2126008810.0, 2147483647.0,

  2147483647.0)

_LOOKUP_TABLE_2 = (4096000000.0, 2048000000.0, 1024000000.0, 512000000.0, 255744255.0, 127110228.0,

  64000000.0, 32258064.0, 16016016.0, 8000000.0, 4000000.0, 2000000.0, 1000000.0,

  500000.0, 250000.0, 125000.0)

def _read24(arr):

  ret = 0.0

  for b in arr:

    ret *= 256.0

    ret += float(b & 0xFF)

  return ret

class Adafruit_BME680:

  def __init__(self, *, refresh_rate=10):

    self._write(_BME680_REG_SOFTRESET, [0xB6])

    time.sleep(0.005)

    chip_id = self._read_byte(_BME680_REG_CHIPID)

    if chip_id != _BME680_CHIPID:

      raise RuntimeError('Failed 0x%x' % chip_id)

    self._read_calibration()

    self._write(_BME680_BME680_RES_HEAT_0, [0x73])

    self._write(_BME680_BME680_GAS_WAIT_0, [0x65])

    self.sea_level_pressure = 1013.25

    self._pressure_oversample = 0b011

    self._temp_oversample = 0b100

    self._humidity_oversample = 0b010

    self._filter = 0b010

    self._adc_pres = None

    self._adc_temp = None

    self._adc_hum = None

    self._adc_gas = None

    self._gas_range = None

    self._t_fine = None

    self._last_reading = 0

    self._min_refresh_time = 1000 / refresh_rate

  @property

  def pressure_oversample(self):

    return _BME680_SAMPLERATES[self._pressure_oversample]

  @pressure_oversample.setter

  def pressure_oversample(self, sample_rate):

    if sample_rate in _BME680_SAMPLERATES:

      self._pressure_oversample = _BME680_SAMPLERATES.index(sample_rate)

    else:

      raise RuntimeError("Invalid")

  @property

  def humidity_oversample(self):

    return _BME680_SAMPLERATES[self._humidity_oversample]

  @humidity_oversample.setter

  def humidity_oversample(self, sample_rate):

    if sample_rate in _BME680_SAMPLERATES:

      self._humidity_oversample = _BME680_SAMPLERATES.index(sample_rate)

    else:

      raise RuntimeError("Invalid")

  @property

  def temperature_oversample(self):

      return _BME680_SAMPLERATES[self._temp_oversample]

  @temperature_oversample.setter

  def temperature_oversample(self, sample_rate):

    if sample_rate in _BME680_SAMPLERATES:

      self._temp_oversample = _BME680_SAMPLERATES.index(sample_rate)

    else:

      raise RuntimeError("Invalid")

  @property

  def filter_size(self):

    return _BME680_FILTERSIZES[self._filter]

  @filter_size.setter

  def filter_size(self, size):

    if size in _BME680_FILTERSIZES:

      self._filter = _BME680_FILTERSIZES[size]

    else:

      raise RuntimeError("Invalid")

  @property

  def temperature(self):

    self._perform_reading()

    calc_temp = (((self._t_fine * 5) + 128) / 256)

    return calc_temp / 100

  @property

  def pressure(self):

    self._perform_reading()

    var1 = (self._t_fine / 2) - 64000

    var2 = ((var1 / 4) * (var1 / 4)) / 2048

    var2 = (var2 * self._pressure_calibration[5]) / 4

    var2 = var2 + (var1 * self._pressure_calibration[4] * 2)

    var2 = (var2 / 4) + (self._pressure_calibration[3] * 65536)

    var1 = (((((var1 / 4) * (var1 / 4)) / 8192) *

      (self._pressure_calibration[2] * 32) / 8) +

      ((self._pressure_calibration[1] * var1) / 2))

    var1 = var1 / 262144

    var1 = ((32768 + var1) * self._pressure_calibration[0]) / 32768

    calc_pres = 1048576 - self._adc_pres

    calc_pres = (calc_pres - (var2 / 4096)) * 3125

    calc_pres = (calc_pres / var1) * 2

    var1 = (self._pressure_calibration[8] * (((calc_pres / 8) * (calc_pres / 8)) / 8192)) / 4096

    var2 = ((calc_pres / 4) * self._pressure_calibration[7]) / 8192

    var3 = (((calc_pres / 256) ** 3) * self._pressure_calibration[9]) / 131072

    calc_pres += ((var1 + var2 + var3 + (self._pressure_calibration[6] * 128)) / 16)

    return calc_pres/100

  @property

  def humidity(self):

    self._perform_reading()

    temp_scaled = ((self._t_fine * 5) + 128) / 256

    var1 = ((self._adc_hum - (self._humidity_calibration[0] * 16)) -

      ((temp_scaled * self._humidity_calibration[2]) / 200))

    var2 = (self._humidity_calibration[1] *

      (((temp_scaled * self._humidity_calibration[3]) / 100) +

       (((temp_scaled * ((temp_scaled * self._humidity_calibration[4]) / 100)) /

         64) / 100) + 16384)) / 1024

    var3 = var1 * var2

    var4 = self._humidity_calibration[5] * 128

    var4 = (var4 + ((temp_scaled * self._humidity_calibration[6]) / 100)) / 16

    var5 = ((var3 / 16384) * (var3 / 16384)) / 1024

    var6 = (var4 * var5) / 2

    calc_hum = (((var3 + var6) / 1024) * 1000) / 4096

    calc_hum /= 1000

    if calc_hum > 100:

      calc_hum = 100

    if calc_hum < 0:

      calc_hum = 0

    return calc_hum

  @property

  def altitude(self):

    pressure = self.pressure

    return 44330 * (1.0 - math.pow(pressure / self.sea_level_pressure, 0.1903))

  @property

  def gas(self):

    self._perform_reading()

    var1 = ((1340 + (5 * self._sw_err)) * (_LOOKUP_TABLE_1[self._gas_range])) / 65536

    var2 = ((self._adc_gas * 32768) - 16777216) + var1

    var3 = (_LOOKUP_TABLE_2[self._gas_range] * var1) / 512

    calc_gas_res = (var3 + (var2 / 2)) / var2

    return int(calc_gas_res)

  def _perform_reading(self):

    if (time.ticks_diff(self._last_reading, time.ticks_ms()) * time.ticks_diff(0, 1)

        < self._min_refresh_time):

      return

    self._write(_BME680_REG_CONFIG, [self._filter << 2])

    self._write(_BME680_REG_CTRL_MEAS,

      [(self._temp_oversample << 5)|(self._pressure_oversample << 2)])

    self._write(_BME680_REG_CTRL_HUM, [self._humidity_oversample])

    self._write(_BME680_REG_CTRL_GAS, [_BME680_RUNGAS])

    ctrl = self._read_byte(_BME680_REG_CTRL_MEAS)

    ctrl = (ctrl & 0xFC) | 0x01

    self._write(_BME680_REG_CTRL_MEAS, [ctrl])

    new_data = False

    while not new_data:

      data = self._read(_BME680_REG_MEAS_STATUS, 15)

      new_data = data[0] & 0x80 != 0

      time.sleep(0.005)

    self._last_reading = time.ticks_ms()

    self._adc_pres = _read24(data[2:5]) / 16

    self._adc_temp = _read24(data[5:8]) / 16

    self._adc_hum = struct.unpack('>H', bytes(data[8:10]))[0]

    self._adc_gas = int(struct.unpack('>H', bytes(data[13:15]))[0] / 64)

    self._gas_range = data[14] & 0x0F

    var1 = (self._adc_temp / 8) - (self._temp_calibration[0] * 2)

    var2 = (var1 * self._temp_calibration[1]) / 2048

    var3 = ((var1 / 2) * (var1 / 2)) / 4096

    var3 = (var3 * self._temp_calibration[2] * 16) / 16384

    self._t_fine = int(var2 + var3)

  def _read_calibration(self):

    coeff = self._read(_BME680_BME680_COEFF_ADDR1, 25)

    coeff += self._read(_BME680_BME680_COEFF_ADDR2, 16)

    coeff = list(struct.unpack('<hbBHhbBhhbbHhhBBBHbbbBbHhbb', bytes(coeff[1:39])))

    coeff = [float(i) for i in coeff]

    self._temp_calibration = [coeff[x] for x in [23, 0, 1]]

    self._pressure_calibration = [coeff[x] for x in [3, 4, 5, 7, 8, 10, 9, 12, 13, 14]]

    self._humidity_calibration = [coeff[x] for x in [17, 16, 18, 19, 20, 21, 22]]

    self._gas_calibration = [coeff[x] for x in [25, 24, 26]]

    self._humidity_calibration[1] *= 16

    self._humidity_calibration[1] += self._humidity_calibration[0] % 16

    self._humidity_calibration[0] /= 16

    self._heat_range = (self._read_byte(0x02) & 0x30) / 16

    self._heat_val = self._read_byte(0x00)

    self._sw_err = (self._read_byte(0x04) & 0xF0) / 16

  def _read_byte(self, register):

    return self._read(register, 1)[0]

  def _read(self, register, length):

    raise NotImplementedError()

  def _write(self, register, values):

    raise NotImplementedError()

class BME680_I2C(Adafruit_BME680):

  def __init__(self, i2c, address=0x77, debug=False, *, refresh_rate=10):

    self._i2c = i2c

    self._address = address

    self._debug = debug

    super().__init__(refresh_rate=refresh_rate)

  def _read(self, register, length):

    result = bytearray(length)

    self._i2c.readfrom_mem_into(self._address, register & 0xff, result)

    if self._debug:

      print("\t${:x} read ".format(register), " ".join(["{:02x}".format(i) for i in result]))

    return result

  def _write(self, register, values):

    if self._debug:

      print("\t${:x} write".format(register), " ".join(["{:02x}".format(i) for i in values]))

    for value in values:

      self._i2c.writeto_mem(self._address, register, bytearray([value & 0xFF]))

      register += 1

 

Ikuti serangkaian instruksi berikut sesuai dengan IDE yang Anda gunakan:

- Unggah Library BME680 dengan uPyCraft IDE

- Unggah Library BME680 dengan Thonny IDE

Unggah Library BME680 dengan uPyCraft IDE

Bagian ini menunjukkan cara mengunggah pustaka menggunakan uPyCraft IDE. Jika Anda menggunakan Thonny IDE, silakan baca bagian berikutnya.

1. Buat file baru dengan menekan tombol New File (1).

2. Salin kode pustaka BME680 ke dalam file tersebut. Kode pustaka BME680 dapat ditemukan [di sini](tautan-kode).

3. Setelah menyalin kode, simpan file dengan menekan tombol Save (2).



4. Beri nama file baru ini `bme680.py` dan tekan OK.

5. Klik tombol Download and Run.

File tersebut akan tersimpan di folder perangkat dengan nama `bme680.py`, seperti yang ditunjukkan pada gambar berikut:



Sekarang, Anda dapat menggunakan fungsi-fungsi pustaka dalam kode Anda dengan mengimpornya.

Unggah Library BME680 dengan Thonny IDE

Jika Anda menggunakan Thonny IDE, ikuti langkah-langkah berikut:

1.  Salin kode library ke dalam file baru.

2.  Buka menu File > Save as….



3. Pilih opsi simpan ke "MicroPython device" (Simpan ke perangkat MicroPython):



4. Beri nama file Anda `bme680.py` dan tekan tombol OK:

Gambar 

Selesai. Pustaka telah berhasil diunggah ke papan Anda. Untuk memastikan pengunggahan berhasil, buka File > Save as… dan pilih MicroPython device. File Anda akan terdaftar di sana:

Gambar 

Setelah pustaka berhasil diunggah ke papan ESP, Anda dapat menggunakan fungsinya dalam kode dengan mengimpornya.

Kode – Suhu, Kelembaban, Tekanan, dan Kualitas Udara (Gas) dari BME680

Setelah mengunggah pustaka ke ESP32 atau ESP8266, salin kode berikut ke file `main.py` atau `boot.py`. Kode ini akan mencetak suhu, kelembaban, tekanan, dan resistansi gas ke shell setiap 5 detik.

 

from machine import Pin, I2C

from time import sleep

from bme680 import *


# ESP32 - Pin assignment

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

# ESP8266 - Pin assignment

#i2c = I2C(scl=Pin(5), sda=Pin(4))


bme = BME680_I2C(i2c=i2c)


while True:

  try:

    temp = str(round(bme.temperature, 2)) + ' C'

    #temp = (bme.temperature) * (9/5) + 32

    #temp = str(round(temp, 2)) + 'F'

    

    hum = str(round(bme.humidity, 2)) + ' %'

    

    pres = str(round(bme.pressure, 2)) + ' hPa'

    

    gas = str(round(bme.gas/1000, 2)) + ' KOhms'


    print('Temperature:', temp)

    print('Humidity:', hum)

    print('Pressure:', pres)

    print('Gas:', gas)

    print('-------')

  except OSError as e:

    print('Failed to read sensor.')

 

  sleep(5)

 

Cara Kerja Kode

Pertama, Anda perlu mengimpor pustaka yang diperlukan, termasuk modul BME680 yang telah Anda unggah sebelumnya.

 

from machine import Pin, I2C

from time import sleep

from bme680 import *

 

Atur pin I2C. Dalam kasus ini, kami menggunakan pin I2C default. Jika Anda menggunakan ESP32, atur pin sebagai berikut:

 

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

 

Jika Anda menggunakan ESP8266, komentari baris sebelumnya dan hapus komentar pada baris berikut sehingga Anda memiliki:

 

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

 

Di dalam perulangan `while`, buat objek BME680 bernama `bme` dengan pin I2C yang telah didefinisikan sebelumnya:

 

bme = BME680_I2C(i2c=i2c)

 

Membaca suhu, kelembaban, tekanan, dan resistansi gas sesederhana menggunakan metode `temperature`, `humidity`, `pressure`, dan `gas` pada objek `bme`.

 

temp = str(round(bme.temperature, 2)) + ' C'

#temp = (bme.temperature) * (9/5) + 32

#temp = str(round(temp, 2)) + 'F'

    

hum = str(round(bme.humidity, 2)) + ' %'

    

pres = str(round(bme.pressure, 2)) + ' hPa'

    

gas = str(round(bme.gas/1000, 2)) + ' KOhms'

 

Terakhir, cetak pembacaan tersebut di shell:

 

print('Temperature: ', temp)

print('Humidity: ', hum)

print('Pressure: ', pres)

print('Gas:', gas)

 

Di akhir, kami menambahkan jeda selama 5 detik:

 

sleep(5)

Demonstrasi

Setelah mengunggah kode ke papan Anda, tekan tombol RST untuk menjalankannya. Pembacaan sensor BME680 baru akan ditampilkan setiap 5 detik.



Menampilkan Pembacaan BME680 pada Web Server

Setelah Anda mengetahui cara membaca suhu, kelembapan, tekanan, dan gas dari sensor BME680, kita akan menampilkan data tersebut pada sebuah web server yang dapat diakses dalam jaringan lokal Anda.


Untuk contoh ini, Anda membutuhkan tiga file:

1. bme680.py: File ini berisi semua metode untuk menggunakan sensor BME680. Ini adalah file yang telah Anda unggah sebelumnya.

2. boot.py: Dijalankan saat perangkat dinyalakan dan mengatur beberapa opsi konfigurasi seperti kredensial jaringan, mengimpor pustaka, mengatur pin, dll.

3. main.py: Ini adalah skrip utama tempat kita akan menangani web server. Skrip ini dieksekusi segera setelah `boot.py`.

Catatan: Adalah praktik yang baik untuk menyertakan file `boot.py` dan `main.py`. Namun, jika Anda lebih suka, Anda dapat menggabungkan semua kode dalam satu file `main.py`.

boot.py

Buat file baru di IDE Anda dengan nama `boot.py` dan salin kode berikut.

 

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()


from bme680 import *


# ESP32 - Pin assignment

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

# ESP8266 - Pin assignment

#i2c = I2C(scl=Pin(5), sda=Pin(4))


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())

 

File ini mengimpor pustaka yang diperlukan, mendefinisikan pin I2C untuk terhubung ke sensor, serta menyambungkan ESP ke jaringan Anda.

 

Dalam kode, kami menggunakan pin I2C default untuk ESP32:

 

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

 

Jika Anda menggunakan ESP8266, komentari baris sebelumnya dan hapus komentar pada baris berikut:

 

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

 

Kemudian, masukkan kredensial jaringan Anda (SSID dan password Wi-Fi) ke dalam variabel berikut:

 

ssid = 'REPLACE_WITH_YOUR_SSID'

password = 'REPLACE_WITH_YOUR_PASSWORD'

 

main.py

Di dalam file `main.py` inilah kita akan membuat web server dan menangani permintaan (requests). Salin kode berikut ke file `main.py` Anda.

 

def web_page():

  bme = BME680_I2C(i2c=i2c)

  

  html = """<html><head><title>ESP with BME680</title>

  <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; 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 BME680</h1>

  <table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>

  <tr><td>Temp. Celsius</td><td><span class="sensor">""" + str(round(bme.temperature, 2)) + """ C</span></td></tr>

  <tr><td>Temp. Fahrenheit</td><td><span class="sensor">""" + str(round((bme.temperature) * (9/5) + 32, 2))  + """ F</span></td></tr>

  <tr><td>Pressure</td><td><span class="sensor">""" + str(round(bme.pressure, 2)) + """ hPa</span></td></tr>

  <tr><td>Humidity</td><td><span class="sensor">""" + str(round(bme.humidity, 2)) + """ %</span></td></tr>

  <tr><td>Gas</td><td><span class="sensor">""" + str(round(bme.gas/1000, 2)) + """ KOhms</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')

 

Kode ini membuat server socket yang mengirimkan halaman HTML berisi pembacaan sensor terbaru setiap kali ada permintaan yang diterima di alamat IP ESP32 atau ESP8266.

 

Pada dasarnya, kita memiliki fungsi bernama `web_page()` yang mengembalikan kode HTML untuk membangun halaman web dengan data sensor terbaru. Teks HTML ini membuat tabel untuk menampilkan pembacaan sensor:

 

def web_page():

  bme = BME680_I2C(i2c=i2c)

  

  html = """<html><head><title>ESP with BME680</title>

  <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; 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 BME680</h1>

  <table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>

  <tr><td>Temp. Celsius</td><td><span class="sensor">""" + str(round(bme.temperature, 2)) + """ C</span></td></tr>

  <tr><td>Temp. Fahrenheit</td><td><span class="sensor">""" + str(round((bme.temperature) * (9/5) + 32, 2))  + """ F</span></td></tr>

  <tr><td>Pressure</td><td><span class="sensor">""" + str(round(bme.pressure, 2)) + """ hPa</span></td></tr>

  <tr><td>Humidity</td><td><span class="sensor">""" + str(round(bme.humidity, 2)) + """ %</span></td></tr>

  <tr><td>Gas</td><td><span class="sensor">""" + str(round(bme.gas/1000, 2)) + """ KOhms</span></td></tr></body></html>"""

  return html

 

Selanjutnya, kita membuat server socket yang mengirimkan HTML saat menerima permintaan. Teks HTML tersebut kemudian disimpan dalam variabel `response`:

 

response = web_page()

 

Dan dikirimkan ke klien:

 

conn.sendall(response)

 

Demonstrasi Web Server

Unggah semua file sebelumnya ke papan ESP32 atau ESP8266 Anda dengan urutan sebagai berikut:

1. `bme680.py`

2. `boot.py`

3. `main.py`

Setelah kode terunggah, alamat IP ESP32 atau ESP8266 Anda akan ditampilkan di Serial Monitor.

Gambar

Buka web browser di dalam jaringan lokal Anda dan ketikkan alamat IP ESP (dalam contoh kami, IP-nya adalah `http://192.168.1.114`). Anda akan mendapatkan halaman yang menampilkan pembacaan sensor terbaru seperti pada gambar berikut.

Gambar

Halaman Web dengan Pembaruan Otomatis (Auto-refresh)

Dengan skrip web server yang disediakan dalam proyek ini, Anda perlu me-refresh halaman web secara manual untuk melihat pembacaan terbaru. Jika Anda menambahkan meta tag berikut di dalam tag `<head></head>` pada HTML, halaman web Anda akan memperbarui diri secara otomatis setiap 10 detik:

 

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









Siap Untuk Membuat Proyek Impianmu Menjadi Kenyataan?

Klik di sini untuk chat langsung via WhatsApp dan dapatkan dukungan langsung dari tim ahli kami! 

 

0 on: "Tutorial MicroPython ESP32 dan ESP8266 - Sensor BME680 untuk Monitoring Suhu, Kelembaban, Tekanan & Gas"