diff --git a/__init__.py b/__init__.py index 3570da1..8b5fe4b 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,33 @@ import logging +import threading +import time +DEBUG = False logger_name = 'RPI_ENVSENS' logger = logging.getLogger(logger_name) + + +class background_task(object): + RUN_SLEEP_TIME = 2.0 + + def __init__(self): + self.__active__ = True + self.__thread__ = threading.Thread(target=self.run, args=()) + self.__thread__.daemon = True # Daemonize thread + self.__thread__.start() # Start the execution + + def __run__(self): + pass + + def run(self): + while self.__active__: + self.__run__() + time.sleep(self.RUN_SLEEP_TIME) + + def close(self): + self.__active__ = False + self.__thread__.join() + + def __del__(self): + self.close() diff --git a/_datasheets_/datasheet.pdf b/_datasheets_/datasheet.pdf new file mode 100644 index 0000000..1f8379f Binary files /dev/null and b/_datasheets_/datasheet.pdf differ diff --git a/_datasheets_/schematic_ardu.pdf b/_datasheets_/schematic_ardu.pdf new file mode 100644 index 0000000..231de56 Binary files /dev/null and b/_datasheets_/schematic_ardu.pdf differ diff --git a/_datasheets_/schematic_rpi.pdf b/_datasheets_/schematic_rpi.pdf new file mode 100644 index 0000000..246c3eb Binary files /dev/null and b/_datasheets_/schematic_rpi.pdf differ diff --git a/bmp.py b/bmp.py index 23d2e79..b24d890 100644 --- a/bmp.py +++ b/bmp.py @@ -1,141 +1,134 @@ -# Distributed with a free-will license. -# Use it any way you want, profit or free, provided it fits in the licenses of its associated works. -# BMP180 -# This code is designed to work with the BMP180_I2CS I2C Mini Module available from ControlEverything.com. -# https://www.controleverything.com/content/Pressure?sku=BMP180_I2CS#tabs-0-product_tabset-2 - -import smbus -import threading import time -from . import logger +from . import logger, background_task, DEBUG +if not DEBUG: + import smbus -class bmp_180(object): +class bmp_180(background_task): + RUN_SLEEP_TIME = 0.5 + SMBUS_DELAY = 0.5 + MIN_REFRESH_RATE = RUN_SLEEP_TIME + 3 * SMBUS_DELAY KEY_TEMPERATURE = 'temperature' KEY_PRESSURE = 'pressure' KEY_TIME = 'time' def __init__(self, data_callback=None): self.__data_callback__ = data_callback - # Initial the dht device, with data pin connected to: - self.__active__ = True - self.__thread__ = threading.Thread(target=self.run, args=()) - self.__thread__.daemon = True # Daemonize thread - self.__thread__.start() # Start the execution + # Initialise background_task + background_task.__init__(self) - def run(self): - while self.__active__: - data = self.__bmp_data_transmission__() - if data is not None: - logger.debug('BMP-Communication: Successfully: %s', repr(data)) - if self.__data_callback__ is not None: - self.__data_callback__(**data) - time.sleep(0.5) - - def close(self): - self.__active__ = False - self.__thread__.join() - - def __del__(self): - self.close() + def __run__(self): + data = self.__bmp_data_transmission__() + if data is not None: + logger.debug('BMP-Communication: Successfully: %s', repr(data)) + if self.__data_callback__ is not None: + self.__data_callback__(**data) def __bmp_data_transmission__(self): - rv = {} - # Get I2C bus - bus = smbus.SMBus(1) + if not DEBUG: + rv = {} + # Get I2C bus + bus = smbus.SMBus(1) + + # BMP180 address, 0x77(119) + # Read data back from 0xAA(170), 22 bytes + data = bus.read_i2c_block_data(0x77, 0xAA, 22) + + # Convert the data + AC1 = data[0] * 256 + data[1] + if AC1 > 32767 : + AC1 -= 65535 + AC2 = data[2] * 256 + data[3] + if AC2 > 32767 : + AC2 -= 65535 + AC3 = data[4] * 256 + data[5] + if AC3 > 32767 : + AC3 -= 65535 + AC4 = data[6] * 256 + data[7] + AC5 = data[8] * 256 + data[9] + AC6 = data[10] * 256 + data[11] + B1 = data[12] * 256 + data[13] + if B1 > 32767 : + B1 -= 65535 + B2 = data[14] * 256 + data[15] + if B2 > 32767 : + B2 -= 65535 + MB = data[16] * 256 + data[17] + if MB > 32767 : + MB -= 65535 + MC = data[18] * 256 + data[19] + if MC > 32767 : + MC -= 65535 + MD = data[20] * 256 + data[21] + if MD > 32767 : + MD -= 65535 + + time.sleep(self.SMBUS_DELAY) + + # BMP180 address, 0x77(119) + # Select measurement control register, 0xF4(244) + # 0x2E(46) Enable temperature measurement + bus.write_byte_data(0x77, 0xF4, 0x2E) + + time.sleep(self.SMBUS_DELAY) + + # BMP180 address, 0x77(119) + # Read data back from 0xF6(246), 2 bytes + # temp MSB, temp LSB + data = bus.read_i2c_block_data(0x77, 0xF6, 2) + + # Convert the data + temp = data[0] * 256 + data[1] + + # BMP180 address, 0x77(119) + # Select measurement control register, 0xF4(244) + # 0x74(116) Enable pressure measurement, OSS = 1 + bus.write_byte_data(0x77, 0xF4, 0x74) + + time.sleep(self.SMBUS_DELAY) + + # BMP180 address, 0x77(119) + # Read data back from 0xF6(246), 3 bytes + # pres MSB1, pres MSB, pres LSB + data = bus.read_i2c_block_data(0x77, 0xF6, 3) + + rv[self.KEY_TIME] = int(time.time()) - # BMP180 address, 0x77(119) - # Read data back from 0xAA(170), 22 bytes - data = bus.read_i2c_block_data(0x77, 0xAA, 22) + # Convert the data + pres = ((data[0] * 65536) + (data[1] * 256) + data[2]) / 128 + # Callibration for Temperature + X1 = (temp - AC6) * AC5 / 32768.0 + X2 = (MC * 2048.0) / (X1 + MD) + B5 = X1 + X2 + rv[self.KEY_TEMPERATURE] = ((B5 + 8.0) / 16.0) / 10.0 + + # Calibration for Pressure + B6 = B5 - 4000 + X1 = (B2 * (B6 * B6 / 4096.0)) / 2048.0 + X2 = AC2 * B6 / 2048.0 + X3 = X1 + X2 + B3 = (((AC1 * 4 + X3) * 2) + 2) / 4.0 + X1 = AC3 * B6 / 8192.0 + X2 = (B1 * (B6 * B6 / 2048.0)) / 65536.0 + X3 = ((X1 + X2) + 2) / 4.0 + B4 = AC4 * (X3 + 32768) / 32768.0 + B7 = ((pres - B3) * (25000.0)) + pressure = 0.0 + if B7 < 2147483648: + pressure = (B7 * 2) / B4 + else : + pressure = (B7 / B4) * 2 + X1 = (pressure / 256.0) * (pressure / 256.0) + X1 = (X1 * 3038.0) / 65536.0 + X2 = ((-7357) * pressure) / 65536.0 + rv[self.KEY_PRESSURE] = (pressure + (X1 + X2 + 3791) / 16.0) / 100 - # Convert the data - AC1 = data[0] * 256 + data[1] - if AC1 > 32767 : - AC1 -= 65535 - AC2 = data[2] * 256 + data[3] - if AC2 > 32767 : - AC2 -= 65535 - AC3 = data[4] * 256 + data[5] - if AC3 > 32767 : - AC3 -= 65535 - AC4 = data[6] * 256 + data[7] - AC5 = data[8] * 256 + data[9] - AC6 = data[10] * 256 + data[11] - B1 = data[12] * 256 + data[13] - if B1 > 32767 : - B1 -= 65535 - B2 = data[14] * 256 + data[15] - if B2 > 32767 : - B2 -= 65535 - MB = data[16] * 256 + data[17] - if MB > 32767 : - MB -= 65535 - MC = data[18] * 256 + data[19] - if MC > 32767 : - MC -= 65535 - MD = data[20] * 256 + data[21] - if MD > 32767 : - MD -= 65535 - - time.sleep(0.5) - - # BMP180 address, 0x77(119) - # Select measurement control register, 0xF4(244) - # 0x2E(46) Enable temperature measurement - bus.write_byte_data(0x77, 0xF4, 0x2E) - - time.sleep(0.5) - - # BMP180 address, 0x77(119) - # Read data back from 0xF6(246), 2 bytes - # temp MSB, temp LSB - data = bus.read_i2c_block_data(0x77, 0xF6, 2) - - # Convert the data - temp = data[0] * 256 + data[1] - - # BMP180 address, 0x77(119) - # Select measurement control register, 0xF4(244) - # 0x74(116) Enable pressure measurement, OSS = 1 - bus.write_byte_data(0x77, 0xF4, 0x74) - - time.sleep(0.5) - - # BMP180 address, 0x77(119) - # Read data back from 0xF6(246), 3 bytes - # pres MSB1, pres MSB, pres LSB - data = bus.read_i2c_block_data(0x77, 0xF6, 3) - - rv[self.KEY_TIME] = time.time() - - # Convert the data - pres = ((data[0] * 65536) + (data[1] * 256) + data[2]) / 128 - # Callibration for Temperature - X1 = (temp - AC6) * AC5 / 32768.0 - X2 = (MC * 2048.0) / (X1 + MD) - B5 = X1 + X2 - rv[self.KEY_TEMPERATURE] = ((B5 + 8.0) / 16.0) / 10.0 - - # Calibration for Pressure - B6 = B5 - 4000 - X1 = (B2 * (B6 * B6 / 4096.0)) / 2048.0 - X2 = AC2 * B6 / 2048.0 - X3 = X1 + X2 - B3 = (((AC1 * 4 + X3) * 2) + 2) / 4.0 - X1 = AC3 * B6 / 8192.0 - X2 = (B1 * (B6 * B6 / 2048.0)) / 65536.0 - X3 = ((X1 + X2) + 2) / 4.0 - B4 = AC4 * (X3 + 32768) / 32768.0 - B7 = ((pres - B3) * (25000.0)) - pressure = 0.0 - if B7 < 2147483648: - pressure = (B7 * 2) / B4 - else : - pressure = (B7 / B4) * 2 - X1 = (pressure / 256.0) * (pressure / 256.0) - X1 = (X1 * 3038.0) / 65536.0 - X2 = ((-7357) * pressure) / 65536.0 - rv[self.KEY_PRESSURE] = (pressure + (X1 + X2 + 3791) / 16.0) / 100 - - return rv + return rv + else: + time.sleep(3 * self.SMBUS_DELAY) + return { + self.KEY_PRESSURE: 1717., + self.KEY_TEMPERATURE: 17.17, + self.KEY_TIME: int(time.time()) + } diff --git a/dht.py b/dht.py index 0407b5e..cfb34d2 100644 --- a/dht.py +++ b/dht.py @@ -1,11 +1,14 @@ -import adafruit_dht -import threading import time -from . import logger +from . import logger, background_task, DEBUG + +if not DEBUG: + import adafruit_dht -class dht_22(object): +class dht_22(background_task): + RUN_SLEEP_TIME = 2.0 + MIN_REFRESH_RATE = RUN_SLEEP_TIME KEY_TEMPERATURE = 'temperature' KEY_HUMIDITY = 'humidity' KEY_TIME = 'time' @@ -13,43 +16,40 @@ class dht_22(object): def __init__(self, gpio, data_callback=None): self.__data_callback__ = data_callback # Initial the dht device, with data pin connected to: - self.__dht_device__ = adafruit_dht.DHT22(gpio) - self.__active__ = True - self.__thread__ = threading.Thread(target=self.run, args=()) - self.__thread__.daemon = True # Daemonize thread - self.__thread__.start() # Start the execution + if not DEBUG: + self.__dht_device__ = adafruit_dht.DHT22(gpio) + # Initialise background_task + background_task.__init__(self) - def run(self): - while self.__active__: - data = self.__dht_data_transmission__() - if data is not None: - logger.debug('DHT-Communication: Successfully: %s', repr(data)) - if self.__data_callback__ is not None: - self.__data_callback__(**data) - time.sleep(2.0) - - def close(self): - self.__active__ = False - self.__thread__.join() - - def __del__(self): - self.close() + def __run__(self): + data = self.__dht_data_transmission__() + if data is not None: + logger.debug('DHT-Communication: Successfully: %s', repr(data)) + if self.__data_callback__ is not None: + self.__data_callback__(**data) def __dht_data_transmission__(self): - while self.__active__: - try: - # Store the values - data = {} - data[self.KEY_TEMPERATURE] = self.__dht_device__.temperature - data[self.KEY_HUMIDITY] = self.__dht_device__.humidity - data[self.KEY_TIME] = time.time() - if data[self.KEY_TEMPERATURE] is not None and data[self.KEY_HUMIDITY] is not None: - return data - time.sleep(2.0) - except RuntimeError as error: - # Errors happen fairly often, DHT's are hard to read, just keep going - logger.debug('DHT-Communication: ' + error.args[0]) - time.sleep(0.1) - except Exception as error: - self.__dht_device__.exit() - raise error + if not DEBUG: + while self.__active__: + try: + # Store the values + data = {} + data[self.KEY_TEMPERATURE] = self.__dht_device__.temperature + data[self.KEY_HUMIDITY] = self.__dht_device__.humidity + data[self.KEY_TIME] = int(time.time()) + if data[self.KEY_TEMPERATURE] is not None and data[self.KEY_HUMIDITY] is not None: + return data + time.sleep(2.0) + except RuntimeError as error: + # Errors happen fairly often, DHT's are hard to read, just keep going + logger.info('DHT-Communication: ' + error.args[0]) + time.sleep(0.1) + except Exception as error: + self.__dht_device__.exit() + raise error + else: + return { + self.KEY_TEMPERATURE: -17.17, + self.KEY_HUMIDITY: 1.7, + self.KEY_TIME: int(time.time()), + }