tum-esm / hermes

https://tenta-on-acropolis.fly.dev/
GNU Affero General Public License v3.0
9 stars 0 forks source link

Improve BME280 Sensor Interface #135

Closed patrickjaigner closed 9 months ago

patrickjaigner commented 10 months ago

ERROR main - exception in mainloop, TypeError: argument must be an int, or have a fileno() method. --- details: ----------------- None --- traceback: --------------- Traceback (most recent call last):

File "/home/pi/Documents/hermes/0.2.0-beta.12/src/main.py", line 151, in run system_check_prodecure.run()

File "/home/pi/Documents/hermes/0.2.0-beta.12/src/procedures/system_check.py", line 32, in run mainboard_bme280_data = self.hardware_interface.mainboard_sensor.get_data()

File "/home/pi/Documents/hermes/0.2.0-beta.12/src/hardware/bme280_sensor.py", line 59, in get_data bme280_data = bme280.sample(

File "/home/pi/Documents/hermes/0.2.0-beta.12/.venv/lib/python3.9/site-packages/bme280/init.py", line 213, in sample bus.write_byte_data(address, 0xF2, h_oversampling) # ctrl_hum

File "/home/pi/Documents/hermes/0.2.0-beta.12/.venv/lib/python3.9/site-packages/smbus2/smbus2.py", line 455, in write_byte_data ioctl(self.fd, I2C_SMBUS, msg)

TypeError: argument must be an int, or have a fileno() method.

patrickjaigner commented 10 months ago

Module: https://pypi.org/project/RPi.bme280/

def sample(bus, address=DEFAULT_PORT, compensation_params=None, sampling=oversampling.x1):
    """
    Primes the sensor for reading (defaut: x1 oversampling), pauses for a set
    amount of time so that the reading stabilizes, and then returns a
    compensated reading object with the following attributes:
        * timestamp (Python's datetime object) when reading was taken.
        * temperature, in degrees Celcius.
        * humidity, in % relative humidity.
        * pressure, in hPa.
    """
    if compensation_params is None:
        compensation_params = __cache_calibration_params(bus, address)

    mode = 1  # forced
    t_oversampling = sampling or oversampling.x1
    h_oversampling = sampling or oversampling.x1
    p_oversampling = sampling or oversampling.x1

    bus.write_byte_data(address, 0xF2, h_oversampling)  # ctrl_hum
    bus.write_byte_data(address, 0xF4, t_oversampling << 5 | p_oversampling << 2 | mode)  # ctrl
    delay = __calc_delay(t_oversampling, h_oversampling, p_oversampling)
    time.sleep(delay)

    block = bus.read_i2c_block_data(address, 0xF7, 8)
    raw_data = uncompensated_readings(block)
    return compensated_readings(raw_data, compensation_params)
patrickjaigner commented 10 months ago

From smbus2

    def write_byte_data(self, i2c_addr, register, value, force=None):
        """
        Write a byte to a given register.

        :param i2c_addr: i2c address
        :type i2c_addr: int
        :param register: Register to write to
        :type register: int
        :param value: Byte value to transmit
        :type value: int
        :param force:
        :type force: Boolean
        :rtype: None
        """
        self._set_address(i2c_addr, force=force)
        msg = i2c_smbus_ioctl_data.create(
            read_write=I2C_SMBUS_WRITE, command=register, size=I2C_SMBUS_BYTE_DATA
        )
        msg.data.contents.byte = value
        ioctl(self.fd, I2C_SMBUS, msg)
patrickjaigner commented 10 months ago

Performing a hardware reset fixes the issue.

There is one example where the hardware reset was delayed for over 1h. Why? 16.11: System 16

patrickjaigner commented 9 months ago

Part of #136