diff options
| author | Blaise Thompson <blaise@untzag.com> | 2021-04-05 17:59:25 -0500 | 
|---|---|---|
| committer | Blaise Thompson <blaise@untzag.com> | 2021-04-05 17:59:25 -0500 | 
| commit | 512896532e5d33797c4db17e53858fe91eeaca68 (patch) | |
| tree | 218ef8f065bd7b7a868c76186d8b746245a48043 | |
| parent | 024cd56cc903a255779e3a189d08f6e45c6d1097 (diff) | |
bme280
| -rw-r--r-- | firmware/bme280.py | 286 | ||||
| -rw-r--r-- | firmware/bme680.py | 229 | ||||
| -rwxr-xr-x | firmware/flash.sh | 6 | ||||
| -rw-r--r-- | firmware/main.py | 28 | 
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__": | 
