aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBlaise Thompson <blaise@untzag.com>2021-04-05 17:59:25 -0500
committerBlaise Thompson <blaise@untzag.com>2021-04-05 17:59:25 -0500
commit512896532e5d33797c4db17e53858fe91eeaca68 (patch)
tree218ef8f065bd7b7a868c76186d8b746245a48043
parent024cd56cc903a255779e3a189d08f6e45c6d1097 (diff)
bme280
-rw-r--r--firmware/bme280.py286
-rw-r--r--firmware/bme680.py229
-rwxr-xr-xfirmware/flash.sh6
-rw-r--r--firmware/main.py28
4 files changed, 298 insertions, 251 deletions
diff --git a/firmware/bme280.py b/firmware/bme280.py
new file mode 100644
index 0000000..7f9c522
--- /dev/null
+++ b/firmware/bme280.py
@@ -0,0 +1,286 @@
+from machine import I2C
+import time
+
+# BME280 default address.
+BME280_I2CADDR = 0x77
+
+# 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}".format(ti, td)
+
+ @property
+ def pressure(self):
+ "Return the temperature in Pa."
+ p = self.read_pressure() // 256
+ p *= 1000 # uPa to Pa
+ pi = p // 100
+ pd = p - pi * 100
+ return "{}.{:02d}".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)
diff --git a/firmware/bme680.py b/firmware/bme680.py
deleted file mode 100644
index 3dfe753..0000000
--- a/firmware/bme680.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# Spaces, comments and some functions have been removed from the original file to save memory
-# 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 # Pa
- @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
diff --git a/firmware/flash.sh b/firmware/flash.sh
index 56287b3..6be74e2 100755
--- a/firmware/flash.sh
+++ b/firmware/flash.sh
@@ -2,7 +2,7 @@
read -p "bring GPIO0 low, reset device, and press enter"
esptool.py --port /dev/ttyUSB0 erase_flash
read -p "bring GPIO0 low, reset device, and press enter"
-esptool.py -p /dev/ttyUSB0 --baud 450800 --chip esp8266 write_flash 0x00000 microhomie-esp8266-v3.0.2.bin
+esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect --verify -fm dio 0x0 ./microhomie-esp8266-v3.0.2.bin
read -p "reset device and press enter"
# upload files
echo "sleeping"
@@ -11,7 +11,7 @@ echo "putting files on device"
ampy -p /dev/ttyUSB0 put main.py
python -m mpy_cross settings.py
ampy -p /dev/ttyUSB0 put settings.mpy
-python -m mpy_cross bme680.py
-ampy -p /dev/ttyUSB0 put bme680.mpy
+python -m mpy_cross bme280.py
+ampy -p /dev/ttyUSB0 put bme280.mpy
read -p "reset device and press enter"
echo "done!"
diff --git a/firmware/main.py b/firmware/main.py
index fe5273b..750eb6c 100644
--- a/firmware/main.py
+++ b/firmware/main.py
@@ -11,7 +11,7 @@ import mqtt_as
mqtt_as.MQTT_base.DEBUG = True
-from bme680 import *
+from bme280 import BME280
from homie.constants import FALSE, TRUE, BOOLEAN, FLOAT, STRING
from homie.device import HomieDevice
@@ -20,13 +20,13 @@ from homie.property import HomieNodeProperty
from uasyncio import get_event_loop, sleep_ms
-class BME680(HomieNode):
+class WeatherSensor(HomieNode):
- def __init__(self, name="bme680", device=None):
- super().__init__(id="bme680", name=name, type="sensor")
+ def __init__(self, name="bme280", device=None):
+ super().__init__(id="bme280", name=name, type="sensor")
self.device = device
self.i2c = I2C(scl=Pin(5), sda=Pin(4))
- self.bme680 = BME680_I2C(i2c=self.i2c)
+ self.bme280 = BME280(i2c=self.i2c)
self.temperature = HomieNodeProperty(
id="temperature",
name="temperature",
@@ -54,15 +54,6 @@ class BME680(HomieNode):
default=0,
)
self.add_property(self.pressure)
- self.gas = HomieNodeProperty(
- id="voc",
- name="voc",
- unit="ohm",
- settable=False,
- datatype=FLOAT,
- default=0,
- )
- self.add_property(self.gas)
self.uptime = HomieNodeProperty(
id="uptime",
name="uptime",
@@ -91,10 +82,9 @@ class BME680(HomieNode):
self.last_online = time.time()
self.online_led.on()
self.led.value(0) # illuminate onboard LED
- self.temperature.data = str(self.bme680.temperature)
- self.humidity.data = str(self.bme680.humidity)
- self.pressure.data = str(self.bme680.pressure)
- self.gas.data = str(self.bme680.gas)
+ self.temperature.data = str(self.bme280.temperature)
+ self.humidity.data = str(self.bme280.humidity)
+ self.pressure.data = str(self.bme280.pressure)
self.uptime.data = self.get_uptime()
self.led.value(1) # onboard LED off
await sleep_ms(15_000)
@@ -127,7 +117,7 @@ def main():
# homie
print("homie main")
homie = HomieDevice(settings)
- homie.add_node(BME680(device=homie))
+ homie.add_node(WeatherSensor(device=homie))
homie.run_forever()
if __name__ == "__main__":