• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вывести значение из библиотеки, кортеж

Space

New member
Нужно как то вывести значение из библиотеки которое запрятано в кортеж и преобразовать в целое число.

Рассказываю поподробнее:
есть библиотека датчика bme280 который измеряет температуру влажность и давление и выводит все это командой bme.values
вот что он выводит:
('26.05C', '1005.01hPa', '46.08%')

в моем случае мне нужно только первое значение чтобы его получить без лишней шелухи команда вот такая bme.values[0]
ну и вывод будет 26.05C
мне нужно как то в переменную Х выводить значение температуры цифрами (то есть 26) без знака Цельсий (.05C).

Я пробовал залазить в саму библиотеку удалять знак Цельсий но увы не помогло. :confused: что меня сильно удивило.
Я думаю есть еще какие-то способы но я не программист, только на помощь знающих людей надежда, уже много всего перечитал.

Попробую прикрутить код библиотеки на всякий случай.



Python:
# Updated 2018

# Document BST-BME280-DS002-15
#

import time
from ustruct import unpack, unpack_from
from array import array

# 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_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_STATUS = 0xF3
BME280_REGISTER_CONTROL = 0xF4

MODE_SLEEP = const(0)
MODE_FORCED = const(1)
MODE_NORMAL = const(3)


class BME280:

    def __init__(self,
                 mode=BME280_OSAMPLE_8,
                 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_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,'
                'BME280_OSAMPLE_8, BME280_OSAMPLE_16'.format(mode))
        self._mode = mode
        self.address = address
        if i2c is None:
            raise ValueError('An I2C object is required.')
        self.i2c = i2c
        self.__sealevel = 101325

        # load calibration data
        dig_88_a1 = self.i2c.readfrom_mem(self.address, 0x88, 26)
        dig_e1_e7 = self.i2c.readfrom_mem(self.address, 0xE1, 7)
        self.dig_T1, self.dig_T2, self.dig_T3, self.dig_P1, \
            self.dig_P2, self.dig_P3, self.dig_P4, self.dig_P5, \
            self.dig_P6, self.dig_P7, self.dig_P8, self.dig_P9, \
            _, self.dig_H1 = unpack("<HhhHhhhhhhhhBB", dig_88_a1)

        self.dig_H2, self.dig_H3, self.dig_H4,\
            self.dig_H5, self.dig_H6 = unpack("<hBbhb", dig_e1_e7)
        # unfold H4, H5, keeping care of a potential sign
        self.dig_H4 = (self.dig_H4 * 16) + (self.dig_H5 & 0xF)
        self.dig_H5 //= 16

        self.t_fine = 0

        # temporary data holders which stay allocated
        self._l1_barray = bytearray(1)
        self._l8_barray = bytearray(8)
        self._l3_resultarray = array("i", [0, 0, 0])

        self._l1_barray[0] = self._mode << 5 | self._mode << 2 | MODE_SLEEP
        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL,
                             bytearray([0x3c | MODE_SLEEP]))

    def read_raw_data(self, result):
        """ Reads the raw (uncompensated) data from the sensor.

            Args:
                result: array of length 3 or alike where the result will be
                stored, in temperature, pressure, humidity order
            Returns:
                None
        """

        self._l1_barray[0] = self._mode
        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL_HUM,
                             self._l1_barray)
        self._l1_barray[0] = self._mode << 5 | self._mode << 2 | MODE_FORCED
        self.i2c.writeto_mem(self.address, BME280_REGISTER_CONTROL,
                             self._l1_barray)

        # Wait for conversion to complete
        while self.i2c.readfrom_mem(self.address, BME280_REGISTER_STATUS, 1)[0] & 0x08:
            time.sleep_ms(10)

        # burst readout from 0xF7 to 0xFE, recommended by datasheet
        self.i2c.readfrom_mem_into(self.address, 0xF7, self._l8_barray)
        readout = self._l8_barray
        # pressure(0xF7): ((msb << 16) | (lsb << 8) | xlsb) >> 4
        raw_press = ((readout[0] << 16) | (readout[1] << 8) | readout[2]) >> 4
        # temperature(0xFA): ((msb << 16) | (lsb << 8) | xlsb) >> 4
        raw_temp = ((readout[3] << 16) | (readout[4] << 8) | readout[5]) >> 4
        # humidity(0xFD): (msb << 8) | lsb
        raw_hum = (readout[6] << 8) | readout[7]

        result[0] = raw_temp
        result[1] = raw_press
        result[2] = raw_hum

    def read_compensated_data(self, result=None):
        """ Reads the data from the sensor and returns the compensated data.

            Args:
                result: array of length 3 or alike where the result will be
                stored, in temperature, pressure, humidity order. You may use
                this to read out the sensor without allocating heap memory

            Returns:
                array with temperature, pressure, humidity. Will be the one
                from the result parameter if not None
        """
        self.read_raw_data(self._l3_resultarray)
        raw_temp, raw_press, raw_hum = self._l3_resultarray
        # temperature
        var1 = (((raw_temp // 8) - (self.dig_T1 * 2)) * self.dig_T2) // 2048
        var2 = (raw_temp // 16) - self.dig_T1
        var2 = (((var2 * var2) // 4096) * self.dig_T3) // 16384
        self.t_fine = var1 + var2
        temp = (self.t_fine * 5 + 128) // 256

        # 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:
            pressure = 0
        else:
            p = ((((1048576 - raw_press) << 31) - var2) * 3125) // var1
            var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
            var2 = (self.dig_P8 * p) >> 19
            pressure = ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)

        # humidity
        h = self.t_fine - 76800
        h = (((((raw_hum << 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
        humidity = h >> 12

        if result:
            result[0] = temp
            result[1] = pressure
            result[2] = humidity
            return result

        return array("i", (temp, pressure, humidity))
#      return array("i", (temp, pressure, humidity))
    @property
    def sealevel(self):
        return self.__sealevel

    @sealevel.setter
    def sealevel(self, value):
        if 300 < value < 1200:  # just ensure some reasonable value
            self.__sealevel = value

    @property
    def altitude(self):
        '''
        Altitude in m.
        '''
        from math import pow
        try:
            p = 44330 * (1.0 - pow((self.read_compensated_data()[1] / 256) /
                                   self.__sealevel, 0.1903))
        except:
            p = 0.0
        return p

    @property
    def dew_point(self):
        """
        Compute the dew point temperature for the current Temperature
        and Humidity measured pair
        """
        from math import log
        t, p, h = self.read_compensated_data()
        t /= 100
        h /= 1024
        h = (log(h, 10) - 2) / 0.4343 + (17.62 * t) / (243.12 + t)
        return (243.12 * h / (17.62 - h)) * 100

    @property
    def values(self):
        """ human readable values """

        t, p, h = self.read_compensated_data()

        p = p / 256

        h = h / 1024
        return ("{}C".format(t / 100), "{:.02f}hPa".format(p/100),
                "{:.02f}%".format(h))
 

CodeNameHawk

Moderator
Команда форума
Курите функцию
bme .read_compensated_data()
они так ее используют
t, p, h = self.read_compensated_data()
видно, что т будет завышена 100 раз.
 

vidok

Member
Незнаю питон.
Может как вариант изменить немного библиотеку:
return ("{}C".format(t / 100), "{:.02f}hPa".format(p/100), "{:.02f}%".format(h))
на
return ("{:d}".format(t / 100), "{:.02f}hPa".format(p/100), "{:.02f}%".format(h))
Вдруг получится:)
 

CodeNameHawk

Moderator
Команда форума
Незнаю питон.
Может как вариант изменить немного библиотеку:
Даже не зная питона, решение найти не проблема, если конечно не забанили в гоогле.
https://www.google.ru/search?newwin...ZgBAKABAaoBB2d3cy13aXrIAQjAAQE&sclient=psy-ab
https://pythontutor.ru/lessons/int_and_float/
https://pythonworld.ru/tipy-dannyx-v-python/chisla-int-float-complex.html
 

Space

New member
Покажите код, где вам что то мешает.
Там где пункт raznic = int(bme.values[0]) - int(temp)

ошибка:
Traceback (most recent call last):
File "<stdin>", line 69, in <module>
ValueError: invalid syntax for integer with base 10


Ну все кидать помидорами разрешаю :LOL:

Код:
import machine
from machine import Pin, I2C, ADC
import ssd1306               
from time import sleep
i2c = I2C(-1, scl=Pin(5), sda=Pin(4)) #  scl=PinD1  Sda=PinD2

import time
time.sleep(2)

svetodiod = machine.Pin(2)
pwm2 = machine.PWM(svetodiod)
pwm2.freq(200)   #частота 0 and 78125
                 #.freq (1) заставляет светодиод мигать один раз в секунду.

pwm2.duty(900)   #DUTY CYCLE - это время, в течение которого импульс включен,
                 # цикл, значение от 0 до 1023 (1023 = off)
  

# ===========пока не раб код таймер===========
# from machine import Timer
# tim = Timer(0)
# tim.init(period=3000, mode=Timer.PERIODIC, callback=lambda x:tim+=1)
# ============================================
# p3 = machine.Pin(2)
# pwm3 = machine.PWM(p3)
# pwm3.duty(550)
# pwm3.freq(2000)

# =====блок шим====================
Peltie = machine.Pin(14)  #Pin(14)  D5
pwm3 = machine.PWM(Peltie)
pwm3.freq(2000)
pwm3.duty(0)   #1023 = on
# =================================

# =====блок датчика температуры====
import bme280_int as bme280     #BME280
bme = bme280.BME280(i2c=i2c)    #BME280
# =================================

# =====блок дисплея================
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
# =================================
pot = ADC(0)   # пин потенциометра

while True:
    temp = pot.read()    # чтение потенциометра
    temp = temp * (24 / 1023)
    
    raznic = int(bme.values[0]) - int(temp)
    
    if raznic >= 7:
        pwm3.duty(1023)
        print("1023_ pwm3.duty(0)")
    elif raznic >= 6:
        pwm3.duty(767)
        print('767_ pwm3.duty(0)')
    elif raznic >= 5:
        pwm3.duty(512)
        print('512_ pwm3.duty(0)')
    elif raznic >= 4:
        pwm3.duty(384)
        print('384_ pwm3.duty(0)')
    elif raznic >= 3:
        pwm3.duty(255)
        print('255_ pwm3.duty(0)')
    elif raznic >= 2:
        pwm3.duty(191)
        print('191_ pwm3.duty(0)')
    elif raznic >= 1:
        pwm3.duty(127)
        print('127_ pwm3.duty(0)')
    else:
        pwm3.duty(0)
        print('0_ pwm3.duty(0)')

    oled.text(bme.values[0], 0, 0)
    oled.text(bme.values[1], 0, 10)
    oled.text(bme.values[2], 0, 20)
    oled.text(str(round(temp)), 0, 30)
#     oled.text(str(tim), 0, 50)
    oled.text("0", 0, 40)
    oled.pixel(5, 63, 1)
    time.sleep(2)
    oled.show()   #показать
    oled.fill(0)  #очистить экран
 

CodeNameHawk

Moderator
Команда форума
Выкиньте все, что не относится к BME280.
Прочитайте температуру и выведите в сериал.
Где команда прочитать температуру?
 

Space

New member
Где команда прочитать температуру?
вот команда : bme.values[0]
она берется из библиотеки.

можно выводить вот так: print(bme.values[0])
и результат будет так: 26.05 С
Знак Цельсия я уже научился удалять ;) а вот целое с него сделать не выходит как я понимаю это кортеж, как обойти кортеж пока не знаю, думал преобразовать в список но я не профи для меня код библиотеки слишком сложный даже чтобы понять что там написано.
 
Сверху Снизу