Пример #1
0
class GroveTemperatureHumiditySensorSHT3x(object):
    def __init__(self, address=0x45, bus=None):
        self.address = address

        # I2C bus
        self.bus = Bus(bus)

    def read(self):
        # high repeatability, clock stretching disabled
        self.bus.write_i2c_block_data(self.address, 0x24, [0x00])

        # measurement duration < 16 ms
        time.sleep(0.016)

        # read 6 bytes back
        # Temp MSB, Temp LSB, Temp CRC, Humididty MSB, Humidity LSB, Humidity CRC
        data = self.bus.read_i2c_block_data(0x45, 0x00, 6)
        temperature = data[0] * 256 + data[1]
        celsius = -45 + (175 * temperature / 65535.0)
        humidity = 100 * (data[3] * 256 + data[4]) / 65535.0
        if data[2] != CRC(data[:2]):
            raise RuntimeError("temperature CRC mismatch")
        if data[5] != CRC(data[3:5]):
            raise RuntimeError("humidity CRC mismatch")
        return celsius, humidity
class GroveTemperatureHumidityAHT20(object):
    def __init__(self, address=0x38, bus=None):
        self.address = address

        # I2C bus
        self.bus = Bus(bus)

    def read(self):
        self.bus.write_i2c_block_data(self.address, 0x00, [0xac, 0x33, 0x00])

        # measurement duration < 16 ms
        time.sleep(0.016)

        data = self.bus.read_i2c_block_data(self.address, 0x00, 6)

        humidity = data[1]
        humidity <<= 8
        humidity += data[2]
        humidity <<= 4
        humidity += (data[3] >> 4)
        humidity /= 1048576.0
        humidity *= 100

        temperature = data[3] & 0x0f
        temperature <<= 8
        temperature += data[4]
        temperature <<= 8
        temperature += data[5]
        temperature = temperature / 1048576.0 * 200.0 - 50.0  # Convert to Celsius

        return temperature, humidity
class Motor(object):
    __MotorSpeedSet = 0x82
    __PWMFrequenceSet = 0x84
    __DirectionSet = 0xaa
    __MotorSetA = 0xa1
    __MotorSetB = 0xa5
    __Nothing = 0x01
    __EnableStepper = 0x1a
    __UnenableStepper = 0x1b
    __Stepernu = 0x1c
    I2CAddr = 0x0f  #Set the address of the I2CMotorDriver
    SPEED_MAX = 100

    def __init__(self, address=0x0f):
        #I2C Port - Grove - I2C Motor Driver V1.3
        self.I2CAddr = address
        self.bus = Bus()
        self.motor = [null, DCMotor(), DCMotor]

    def __del__(self):
        self.set_speed(0, 0)

    #Maps speed from 0-100 to 0-255
    def _map_vals(self, value, leftMin, leftMax, rightMin, rightMax):
        #http://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
        # Figure out how 'wide' each range is
        leftSpan = leftMax - leftMin
        rightSpan = rightMax - rightMin

        # Convert the left range into a 0-1 range (float)
        valueScaled = float(value - leftMin) / float(leftSpan)

        # Convert the 0-1 range into a value in the right range.
        return int(rightMin + (valueScaled * rightSpan))

    def update(self):
        self.set_dir(self.motor[1].clockwise, self.motor[2].clockwise)
        self.set_speed(self.motor[1].speed, self.motor[2].speed)

    #Set motor speed
    def set_speed(self, speed1=0, speed2=0):
        s1 = self._map_vals(speed1, 0, 100, 0, 255)
        s2 = self._map_vals(speed2, 0, 100, 0, 255)
        self.bus.write_i2c_block_data(self.I2CAddr, self.__MotorSpeedSet,
                                      [s1, s2])
        time.sleep(.02)

    #Set motor direction
    def set_dir(self, clock_wise1=True, clock_wise2=True):
        dir1 = 0b10 if clock_wise1 else 0b01
        dir2 = 0b10 if clock_wise2 else 0b01
        dir = (dir2 << 2) | dir1
        self.bus.write_i2c_block_data(self.I2CAddr, self.__DirectionSet,
                                      [dir, 0])
        time.sleep(.02)
Пример #4
0
class I2C_Station:
    def __init__(self,
                 weather_sensor_address=Config.I2C_WEATHER_SENSOR_ADDRESS,
                 bus=None):
        self.weather_sensor_address = weather_sensor_address
        self.bus = Bus(bus)

        if Config.ENABLE_POWERGAUGE:
            self.powergauge_module = LC709203F(
                board.I2C(), address=Config.I2C_POWERGAUGE_ADDRESS)

    def CRC(self, data):
        crc = 0xff
        for s in data:
            crc ^= s
            for _ in range(8):
                if crc & 0x80:
                    crc <<= 1
                    crc ^= 0x131
                else:
                    crc <<= 1
        return crc

    def read_weather_data(self):
        self.bus.write_i2c_block_data(self.weather_sensor_address, 0x24,
                                      [0x00])

        time.sleep(0.016)

        data = self.bus.read_i2c_block_data(self.weather_sensor_address, 0x00,
                                            6)

        temperature = data[0] * 256 + data[1]
        celsius = -45 + (175 * temperature / 65535.0)
        humidity = 100 * (data[3] * 256 + data[4]) / 65535.0

        return celsius, humidity

    def get_power_stats(self):
        try:
            voltage = self.powergauge_module.cell_voltage
            power = self.powergauge_module.cell_percent
        except Exception as e:
            voltage = None
            power = None

        return power, voltage
class GroveTemperatureHumiditySensorSHT3x(object):
    def __init__(self, address=0x45, bus=None):
        self.address = address

        # I2C bus
        self.bus = Bus(bus)

    def CRC(self, data):
        crc = 0xff
        for s in data:
            crc ^= s
            for i in range(8):
                if crc & 0x80:
                    crc <<= 1
                    crc ^= 0x131
                else:
                    crc <<= 1
        return crc

    def read(self):
        # High repeatability, clock stretching disabled
        self.bus.write_i2c_block_data(self.address, 0x24, [0x00])

        # Measurement duration < 16 ms
        time.sleep(0.016)

        # Read 6 bytes back:
        # Temp MSB, Temp LSB, Temp CRC,
        # Humididty MSB, Humidity LSB, Humidity CRC
        data = self.bus.read_i2c_block_data(0x45, 0x00, 6)
        temperature = data[0] * 256 + data[1]
        celsius = -45 + (175 * temperature / 65535.0)
        humidity = 100 * (data[3] * 256 + data[4]) / 65535.0
        if data[2] != self.CRC(data[:2]):
            raise RuntimeError("Temperature CRC mismatch")
        if data[5] != self.CRC(data[3:5]):
            raise RuntimeError("Humidity CRC mismatch")
        return celsius, humidity
Пример #6
0
class GroveAlphanumDisplay(object):
    def __init__(self,
                 address=0x71,
                 brightness=BRIGHT_DEFAULT,
                 display_type=FOUR_TUBES):
        """
        Constructor

        Args:
            address: I2C address, default is 0x71
            brightness: Startup brightness, value between 0 and 15
            display_type: Display type, can be one of 0: FOUR_TUBES and 1: TWO_TUBES
        """
        self.address = address
        self.display_type = display_type
        self.font = display_font4 if display_type == FOUR_TUBES else display_font2
        self.first_dot = False
        self.second_dot = False

        self.bus = Bus()
        self.data = [0] * 4 if self.display_type == FOUR_TUBES else 2

        self.bus.write_i2c_block_data(self.address, REG_INIT, [])
        self.bus.write_i2c_block_data(self.address, DISP_ON, [])
        self.set_brightness(brightness)

    def clear(self):
        """
        Clear display
        """
        self.data = [0] * 4 if self.display_type == FOUR_TUBES else 2
        self.first_dot = False
        self.second_dot = False
        self._show()

    def show(self, data):
        """
        Show a string on the display

        Args:
            data: String to show. If it is longer than the display size (2 or 4),
                  the string is trimmed to display length.
        """
        if type(data) is str:
            self.data = [0] * 4 if self.display_type == FOUR_TUBES else 2
            length = min(len(data), len(self.data))
            for i in range(length):
                self.data[i] = self.font.get(data[i], 0)
        else:
            raise ValueError('Not support {}'.format(type(data)))
        self._show()

    def _show(self):
        """
        Internal function to show the display data.
        First, create the I2C data to write to the display controller and then send it.
        """
        wire_bytes = [0, 0]
        byte_10 = 0
        byte_11 = 0

        if self.display_type == FOUR_TUBES:
            for d in self.data:
                wire_bytes += [d & 0xFF, (d >> 8) & 0xFF]
            for i, d in enumerate(self.data):
                if i == 0:
                    byte_10 |= (1 if (d & 0x02) else 0) << 4
                    byte_10 |= (1 if (d & 0x04) else 0) << 3
                elif i == 1:
                    byte_10 |= (1 if (d & 0x02) else 0) << 6
                    byte_11 |= (1 if (d & 0x04) else 0) << 6
                elif i == 2:
                    byte_10 |= (1 if (d & 0x02) else 0) << 5
                    byte_11 |= (1 if (d & 0x04) else 0) << 1
                else:
                    byte_11 |= (1 if (d & 0x02) else 0) << 2
                    byte_11 |= (1 if (d & 0x04) else 0) << 0

            if self.first_dot:
                byte_10 |= self.font['first_dot'] & 0xFF
                byte_11 |= (self.font['first_dot'] >> 8) & 0xFF
            if self.second_dot:
                byte_10 |= self.font['second_dot'] & 0xFF
                byte_11 |= (self.font['second_dot'] >> 8) & 0xFF

        else:
            for i in [1, 0]:
                value = self.data[i]
                if i == 1 and self.first_dot:
                    value |= self.font['dot']
                if i == 0 and self.second_dot:
                    value |= self.font['dot']
                wire_bytes += [(value >> 8) & 0xFF, value & 0xFF]

            wire_bytes += [0] * 4

        wire_bytes += [byte_10, byte_11]

        self.bus.write_i2c_block_data(self.address, 0, wire_bytes)

    def set_brightness(self, brightness):
        """
        Sets the LED brightness.

        Args:
            brightness: Brightness as integer, value between 0 and 15
        """
        if brightness > BRIGHT_HIGHEST or brightness < 0:
            brightness = BRIGHT_HIGHEST

        self.bus.write_byte(self.address, REG_BRIGHT | brightness)

    def set_blink_type(self, blink_type):
        """
        Configures the blinking of the display, can be one of:
            - 0: No blinking
            - 1: Blink with 2 Hz
            - 2: Blink with 1 Hz

        Args:
            blink_type: Blinking type
        """
        if 0 <= blink_type <= 2:
            self.bus.write_byte(self.address, 0x81 | (blink_type << 1))

    def set_dots(self, first, second):
        """
        Sets the dots in the display.

        Args:
            first: If set, the first/upper dot is on
            second: If set, the second/lower dot is on
        """
        self.first_dot = first
        self.second_dot = second
        self._show()
Пример #7
0
class SGP30:

    def __init__(self):
        self.bus = Bus()

        # SGB30 i2c default address is 0x58
        self.address = 0x58
        self.crc_status = [0, 0]
        self.CO2eq = 0
        self.TVOC = 0
        self.CO2eq_raw = 0
        self.TVOC_raw = 0
        self.CO2eq_baseline = 0
        self.TVOC_baseline = 0

    #########################################
    # Command functions                     #
    #########################################

    # Init air quality command
    # A new “Init_air_quality” command has to be sent after every power-up or soft reset.
    def init_air_quality(self):
        command = ([0x20, 0x03], 0, 10)
        try:
            self.read_write(command)
        except Exception:
            # On fail return 0
            print("sgp30 Init Fail!")
            return 0
        else:
            print("sgp30 Init Ok!")
            # Command pass return 1
            return 1

    # Measure compensated Co2eq and TVOC values
    # Has to be sent regular intervals 1s to ensure proper operation of dynamic baseline correction algorithm
    def measure_air_quality(self):
        command = ([0x20, 0x08], 6, 12)
        data = self.read_write(command)

        if self.crc_status[0] == 0:
            print("Measurement CRC check failed", self.crc_status)
            self.CO2eq = 0
            self.TVOC = 0
            return 0
        else:
            self.CO2eq = bytes_to_int(data[0:2])
            self.TVOC = bytes_to_int(data[3:5])
            return 1

    # Get compensation baseline values
    #
    def get_baseline(self):
        command = ([0x20, 0x15], 6, 10)
        try:
            data = self.read_write(command)
        except Exception:
            # On fail return 0
            print("get_baseline() => read_write() failed.")
            return 0

        if self.crc_status[0] == 0:
            print("Basevalue read CRC check failed", self.crc_status)
            return 0
        else:
            self.CO2eq_baseline = bytes_to_int(data[0:2])
            self.TVOC_baseline = bytes_to_int(data[3:5])
            return 1

    # Set compensation baseline values
    # Sets also variables sgp30(Instance).CO2eq_baseline and sgp30(Instance).TVOC_baseline
    def set_baseline(self, message):
        command = ([0x20, 0x1e], 0, 10)
        formatted_data = []

        # generate correct message format [HByte, LByte, CRC, HByte, LByte, CRC, ...]
        for number in message:
            tmp_bytes = int_to_bytes(number)
            crc = calc_crc8(tmp_bytes)
            formatted_data.extend(tmp_bytes)
            formatted_data.append(crc)

        # Extend command data with with message
        command[0].extend(formatted_data)

        try:
            self.read_write(command)
        except Exception:
            # On fail return 0
            print("set_baseline() => read_write() failed.")
            return 0
        else:
            self.TVOC_baseline = message[0]
            self.CO2eq_baseline = message[1]
            print("Compensation baseline values writen successfully.")
            return 1

    # Set humidity compensation value
    #
    def set_humidity(self, message):
        command = ([0x20, 0x61], 0, 10)
        formatted_data = []

        # generate correct message format [HByte, LByte, CRC, HByte, LByte, CRC, ...]
        for number in message:
            tmp_bytes = int_to_bytes(number)
            crc = calc_crc8(tmp_bytes)
            formatted_data.extend(tmp_bytes)
            formatted_data.append(crc)

        # Extend command data with with message
        command[0].extend(formatted_data)

        try:
            self.read_write(command)
        except Exception:
            # On fail return 0
            print("set_humidity() => read_write() failed.")
            return 0
        else:
            print("Humidity compensation value writen successfully.")
            return 1

    # Measure test
    # The command “Measure_test” which is included for integration and production line testing runs an on-chip
    # self-test. In case of a successful self-test the sensor returns the fixed data pattern 0xD400 (with correct CRC)
    def measure_test(self):
        command = ([0x20, 0x32], 3, 220)
        data = self.read_write(command)

        if self.crc_status[0] == 0:
            print("Measurement CRC check failed", self.crc_status)
            return 0
        else:
            print("On-chip self-test succesfull!")
            return bytes_to_int(data[0:2])

    def get_feature_set_version(self):
        command = ([0x20, 0x2f], 3, 2)
        data = self.read_write(command)

        print("Product type: ", '{0:08b}'.format(data[0])[0:4])
        print("Product version: ", '{0:08b}'.format(data[1]) + ", " + str(data[1]))

    def measure_raw_signals(self):
        command = ([0x20, 0x50], 6, 25)
        data = self.read_write(command)

        if self.crc_status[0] == 0:
            print("Measurement CRC check failed", self.crc_status)
            self.CO2eq_raw = 0
            self.TVOC_raw = 0
            return 0
        else:
            self.CO2eq_raw = bytes_to_int(data[0:2])
            self.TVOC_raw = bytes_to_int(data[3:5])
            return 1

    # Soft reset command
    # A sensor reset can be generated using the “General Call” mode according to I2C-bus specification.
    # It is important to understand that a reset generated in this way is not device specific.
    # All devices on the same I2C bus that support the General Call mode will perform a reset.
    def soft_reset(self):
        command = ([0x00, 0x06], 0, 10)
        self.read_write(command)

    # Get serial ID
    def get_serial_id(self):
        command = ([0x36, 0x82], 9, 10)
        data = self.read_write(command)

        if self.crc_status[0] == 0:
            print("Measurement CRC check failed", self.crc_status)
            return 0
        else:
            print("Get serial succesfull!")
            print("Serial part 1: ", '{0:016b}'.format(bytes_to_int(data[0:2])))
            print("Serial part 2: ", '{0:016b}'.format(bytes_to_int(data[3:5])))
            print("Serial part 3: ", '{0:016b}'.format(bytes_to_int(data[7:9])))
            return 1

    #########################################
    # read and write data to the sgp30      #
    #########################################
    def read_write(self, command):
        if command[1] <= 0:
            # Write to I2C-bus
            # write_i2c_block_data(address, offset, [data_bytes])
            # Note that second offset byte is [data_bytes][0]
            self.bus.write_i2c_block_data(self.address, command[0][0], command[0][1:])
            sleep(command[2]/1000)
            return 1
        else:
            # Read (Write and read) from I2C-Bus
            # write_i2c_block_data(address, offset, [data_bytes])
            # Note that second offset byte is [data_bytes][0]
            # read_i2c_block_data(address, offset, number_of_data_bytes)
            self.bus.write_i2c_block_data(self.address, command[0][0], [command[0][1]])
            sleep(command[2]/1000)
            data = self.bus.read_i2c_block_data(self.address, 0, command[1])
            self.crc_status = validate_crc8(data)
            return data
Пример #8
0
class DHT(object):
    DHT_TYPE = {'DHT11': '11', 'DHT22': '22', 'DHT10': '10'}

    DEFAULT_ADDR = 0x38
    RESET_REG_ADDR = 0xba
    MAX_CNT = 320
    PULSES_CNT = 41

    def __init__(self, dht_type, pin=12, bus_num=1):
        if dht_type != self.DHT_TYPE['DHT11'] and dht_type != self.DHT_TYPE[
                'DHT22'] and dht_type != self.DHT_TYPE['DHT10']:
            print('ERROR: Please use 11|22|10 as dht type.')
            exit(1)
        self.dht_type = dht_type
        if dht_type == self.DHT_TYPE['DHT10']:
            self.bus = Bus(bus_num)
            self.addr = self.DEFAULT_ADDR
            self._dht10_init()
        else:
            self.pin = GPIO(pin, GPIO.OUT)
            self._last_temp = 0.0
            self._last_humi = 0.0

    @property
    def dht_type(self):
        return self._dht_type

    @dht_type.setter
    def dht_type(self, type):
        self._dht_type = type

    ######################## dht10 ############################

    def _dht10_start_mess(self):
        reg_set = [0x33, 0x00]
        self.bus.write_i2c_block_data(self.addr, 0xac, reg_set)

    def _dht10_reset(self):
        self.bus.write_byte(self.addr, self.RESET_REG_ADDR)

    def _dht10_set_system_cfg(self):
        reg_set = [0x08, 0x00]
        self.bus.write_i2c_block_data(self.addr, 0xe1, reg_set)

    def _dht10_read_status(self):
        return self.bus.read_byte_data(self.addr, 0)

    def _dht10_init(self):

        time.sleep(.5)
        self._dht10_reset()
        # delay is needed after reset
        time.sleep(.3)

        self._dht10_set_system_cfg()
        status = self._dht10_read_status()
        # we must check the calibrate flag, bit[3] : 1 for calibrated ok,0 for Not calibrated.
        while status & 0x08 != 0x08:
            print("try calibrated again!n\n")
            self._dht10_reset()
            time.sleep(.5)
            self.bus.dth10_set_system_cfg()
            status = self._dht10_read_status()
            time.sleep(.5)

    #########################################################
    def _read(self):
        if self.dht_type == self.DHT_TYPE['DHT10']:
            t = 0
            h = 0
            self._dht10_start_mess()
            time.sleep(.075)
            # we must check the device busy flag, bit[7] : 1 for busy ,0 for idle.
            while (self._dht10_read_status() & 0x80) != 0:
                time.sleep(.5)
                print("wait for device not busy")
            from smbus2 import SMBus, i2c_msg, SMBusWrapper
            with SMBusWrapper(1) as bus:
                msg = i2c_msg.read(self.addr, 6)
                data = bus.i2c_rdwr(msg)
            data = list(msg)
            t = (t | data[1]) << 8
            t = (t | data[2]) << 8
            t = (t | data[3]) >> 4

            h = (h | data[3]) << 8
            h = (h | data[4]) << 8
            h = (h | data[5]) & 0xfffff

            t = t * 100.0 / 1024 / 1024
            h = h * 200.0 / 1024 / 1024 - 50
            return t, h
        # Send Falling signal to trigger sensor output data
        # Wait for 20ms to collect 42 bytes data
        else:
            self.pin.dir(GPIO.OUT)

            self.pin.write(1)
            time.sleep(.2)

            self.pin.write(0)
            time.sleep(.018)

            self.pin.dir(GPIO.IN)
            # a short delay needed
            for i in range(10):
                pass

            # pullup by host 20-40 us
            count = 0
            while self.pin.read():
                count += 1
                if count > self.MAX_CNT:
                    # print("pullup by host 20-40us failed")
                    return None, "pullup by host 20-40us failed"

            pulse_cnt = [0] * (2 * self.PULSES_CNT)
            fix_crc = False
            for i in range(0, self.PULSES_CNT * 2, 2):
                while not self.pin.read():
                    pulse_cnt[i] += 1
                    if pulse_cnt[i] > self.MAX_CNT:
                        # print("pulldown by DHT timeout %d" % i)
                        return None, "pulldown by DHT timeout %d" % i

                while self.pin.read():
                    pulse_cnt[i + 1] += 1
                    if pulse_cnt[i + 1] > self.MAX_CNT:
                        # print("pullup by DHT timeout %d" % (i + 1))
                        if i == (self.PULSES_CNT - 1) * 2:
                            # fix_crc = True
                            # break
                            pass
                        return None, "pullup by DHT timeout %d" % i

            total_cnt = 0
            for i in range(2, 2 * self.PULSES_CNT, 2):
                total_cnt += pulse_cnt[i]

            # Low level ( 50 us) average counter
            average_cnt = total_cnt / (self.PULSES_CNT - 1)
            # print("low level average loop = %d" % average_cnt)

            data = ''
            for i in range(3, 2 * self.PULSES_CNT, 2):
                if pulse_cnt[i] > average_cnt:
                    data += '1'
                else:
                    data += '0'

            data0 = int(data[0:8], 2)
            data1 = int(data[8:16], 2)
            data2 = int(data[16:24], 2)
            data3 = int(data[24:32], 2)
            data4 = int(data[32:40], 2)

            if fix_crc and data4 != ((data0 + data1 + data2 + data3) & 0xFF):
                data4 = data4 ^ 0x01
                data = data[0:self.PULSES_CNT - 2] + ('1' if data4
                                                      & 0x01 else '0')

            if data4 == ((data0 + data1 + data2 + data3) & 0xFF):
                if self._dht_type == self.DHT_TYPE['DHT11']:
                    humi = int(data0)
                    temp = int(data2)
                elif self._dht_type == self.DHT_TYPE['DHT22']:
                    humi = float(int(data[0:16], 2) * 0.1)
                    temp = float(
                        int(data[17:32], 2) * 0.2 * (0.5 - int(data[16], 2)))
            else:
                # print("checksum error!")
                return None, "checksum error!"

            return humi, temp

    def read(self, retries=15):
        for i in range(retries):
            humi, temp = self._read()
            if not humi is None:
                break
        if humi is None:
            return self._last_humi, self._last_temp
        self._last_humi, self._last_temp = humi, temp
        return humi, temp
Пример #9
0
class Grove12KeyCapTouchMpr121():
    def __init__(self,bus_num = 1,addr = TOUCH_SENSOR_DEFAULT_ADDR):
        self.bus = Bus(bus_num)
        self.addr = addr
        self.threshold = 0
        self.touch_flag = [0]*CHANNEL_NUM

    def sensor_init(self):
        self._set_mode(STOP_MODE)
        data = [0x23,0x10]
        self._set_global_param(data)
        self._set_debounce(0x22)
        self._set_mode(NORMAL_MODE)

    def set_threshold(self,threshold):
        self.threshold = threshold

    def wait_for_ready(self):
        time.sleep(.2)

    def _set_mode(self,mode):
        self.bus.write_byte_data(self.addr,MODE_CONFIG_REG_ADDR,mode)
    
    def _set_global_param(self,data):
        self.bus.write_i2c_block_data(self.addr,GLOBAL_PARAM_REG_ADDR_L,data)
    
    def _set_debounce(self,data):
        self.bus.write_byte_data(self.addr,SET_DEBOUNCE_REG_ADDR,data)

    def _check_status_register(self):
        data_status = self.bus.read_i2c_block_data(self.addr,TOUCH_STATUS_REG_ADDR_L,2)
        return data_status
    
    def get_filtered_touch_data(self,sensor_status):
        result_value = []
        for i in range(CHANNEL_NUM):
            time.sleep(.01)
            if(sensor_status & (1<<i)):
                channel_data = self.bus.read_i2c_block_data(self.addr,FILTERED_DATA_REG_START_ADDR_L+2*i,2)
                result_value.append(channel_data[0] | channel_data[1]<<8 )
            else:
                result_value.append(0)
        return result_value

    def listen_sensor_status(self):
        data = self._check_status_register()
        touch_status = data[0] | (data[1]<<8) 
        touch_result_value = self.get_filtered_touch_data(touch_status)

        for i in range(CHANNEL_NUM):
            if(touch_result_value[i] < self.threshold ):
                touch_result_value[i] = 0
        return touch_result_value
    
    def parse_and_print_result(self,result):
        for i in range(CHANNEL_NUM):
            if(result[i] != 0):
                if(0 == self.touch_flag[i]):
                    self.touch_flag[i] = 1
                    print("Channel %d is pressed,value is %d" %(i,result[i]))
            else:
                if(1 == self.touch_flag[i]):
                    self.touch_flag[i] = 0
                    print("Channel %d is released,value is %d" %(i,result[i]))
Пример #10
0
class I2CStepperMotor(StepperMotor):
    __REG_GET_PID = 0x00
    __REG_GET_VID = 0x01
    __REG_GET_VER = 0x02
    __REG_STP_EN = 0x1A
    __REG_STP_DIS = 0x1B
    __REG_STP_RUN = 0x1C
    __REG_STP_INTERVAL = 0x1D
    __REG_SEQ_LEN = 0x20
    __REG_SEQ_XET = 0x21
    __REG_SET_SPEED = 0x82
    __REG_SET_FREQ = 0x84
    __REG_SET_A = 0xA1
    __REG_SET_B = 0xA5
    __REG_SET_DIR = 0xAA

    def __init__(self, arguments, address=0x0F):
        super(I2CStepperMotor, self).__init__(arguments)
        self._addr = address
        self._bus = Bus()
        self._ang_left = 0
        self._load_seq(arguments["sequences"])

    def __del__(self):
        self.set_speed(0, 0)
        pass

    #Maps speed from 0-100 to 0-255
    def _map_vals(self, value, leftMin, leftMax, rightMin, rightMax):
        #http://stackoverflow.com/questions/1969240/mapping-a-range-of-values-to-another
        # Figure out how 'wide' each range is
        leftSpan = leftMax - leftMin
        rightSpan = rightMax - rightMin

        # Convert the left range into a 0-1 range (float)
        valueScaled = float(value - leftMin) / float(leftSpan)

        # Convert the 0-1 range into a value in the right range.
        return int(rightMin + (valueScaled * rightSpan))

    #Set motor speed
    def set_speed(self, speed1=0, speed2=0):
        s1 = self._map_vals(speed1, 0, 100, 0, 255)
        s2 = self._map_vals(speed2, 0, 100, 0, 255)
        self._bus.write_i2c_block_data(self._addr, self.__REG_SET_SPEED,
                                       [s1, s2])
        time.sleep(.02)

    #Set motor direction
    def set_dir(self, clock_wise1=True, clock_wise2=True):
        dir1 = 0b10 if clock_wise1 else 0b01
        dir2 = 0b10 if clock_wise2 else 0b01
        dir = (dir2 << 2) | dir1
        self._bus.write_i2c_block_data(self._addr, self.__REG_SET_DIR,
                                       [dir, 0])
        time.sleep(.02)

    def _load_seq(self, seq):
        length = len(seq)
        self._bus.write_word_data(self._addr, self.__REG_SEQ_LEN, length)
        for i in range(len(seq)):
            self._bus.write_word_data(self._addr, self.__REG_SEQ_XET, seq[i])

    def _enable(self, en):
        cmd = self.__REG_STP_EN if en else self.__REG_STP_DIS
        if en:
            self.set_speed(self.DC_SPEED_MAX, self.DC_SPEED_MAX)
        else:
            self.set_speed(0, 0)
        self._bus.write_i2c_block_data(self._addr, cmd, [self._dir, 0])
        time.sleep(0.001)

    def _speed(self, rpm):
        self._dir = self._DIR_CLKWISE if rpm >= 0 else self._DIR_ANTI_CLKWISE
        # absolute angle per second
        aps = abs(rpm) * 360.0 / 60.0
        # steps per second, include reductor ratio.
        sps = self._angle2steps(aps)
        period = int(1000000 / sps)  # us
        period = period // 10  # STP_INTERVAL, 10 us
        # print("period = %d us" % (period * 10))
        self._bus.write_word_data(self._addr, self.__REG_STP_INTERVAL, period)
        time.sleep(0.001)

    def _rotate(self, angle=None):
        if not angle is None:
            angle = abs(angle)
            self._ang_left = angle
            steps = self._angle2steps(angle)
            # print("steps set = {}".format(steps))
            self._bus.write_word_data(self._addr, self.__REG_STP_RUN, steps)
            time.sleep(0.001)
            return angle
        while True:
            # reading interface unstable when working
            try:
                steps = self._bus.read_word_data(self._addr,
                                                 self.__REG_STP_RUN)
                # print("steps left = {}".format(steps))
                ang_left = self._steps2angle(steps)
                if ang_left > self._ang_left:
                    time.sleep(0.01)
                    continue
                self._ang_left = ang_left
                return ang_left
            except IOError:
                continue
Пример #11
0
class bme280:
    """
    Grove bme280 sensor control library.
    Objects:
        - set_mode(mode, t_sb)
        - set_oversampling(osrs_h, osrs_t, osrs_p)
        - set_filter(filter_coefficient)
        - set_spi(spi3w_en)
        - write_reset()
        - read_id()
        - read_status()
        - read_compensated_signals()
        - read_raw_signals()
        - set_pressure_calibration(level, pressure)
        - get_altitude(pressure)
    """

    # Constant Definitions
    # Modes
    MODE_SLEEP = 0b00
    MODE_FORCE = 0b01
    MODE_NORMAL = 0b11

    # Normal mode standby values
    t_sb_0_5 = 0b000
    t_sb_62_5 = 0b001
    t_sb_125 = 0b010
    t_sb_250 = 0b011
    t_sb_500 = 0b100
    t_sb_1000 = 0b101
    t_sb_10 = 0b110
    t_sb_20 = 0b111

    # IIR filter coefficient
    filter_0 = 0b000
    filter_2 = 0b001
    filter_4 = 0b010
    filter_8 = 0b011
    filter_16 = 0b100

    # SPI control
    SPI_ON = 0b01
    SPI_OFF = 0b00

    # Oversampling modes
    OVRS_x0 = 0b000
    OVRS_x1 = 0b001
    OVRS_x2 = 0b010
    OVRS_x4 = 0b011
    OVRS_x8 = 0b100
    OVRS_x16 = 0b101

    def __init__(self):
        # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1,  Rev 1 Pi uses bus 0
        # bme280 default I2C Address is 0x76
        self.bus = Bus()
        self.address = 0x76
        self.mode = self.MODE_SLEEP
        self.t_sb = self.t_sb_1000
        self.last_meas = 0

        # Calibration data
        # Calibration data registers are 0x88-0xA1(25 bytes) and 0xE1-0xE7(7 bytes) total 32 bytes
        self.calib = [0x00] * 32

        # Init raw data array and variables
        self.raw_data = [0x00] * 8
        self.raw_temperature = 0x00000
        self.raw_pressure = 0x00000
        self.raw_humidity = 0x00000

        # Init parameters
        self.osrs_h = self.OVRS_x0
        self.osrs_t = self.OVRS_x0
        self.osrs_p = self.OVRS_x0

        # IIR filter and SPI interface are off by default
        self.filter = self.filter_0
        self.spi3w_en = self.SPI_OFF

        # Status word. Only has two significant bits bit0 = im_update and bit3 = measuring
        self.status = 0x00
        self.im_update = False
        self.measuring = False

        # Compensation values
        # Temperature trimming values
        self.dig_T1 = 0x0000
        self.dig_T2 = 0x0000
        self.dig_T3 = 0x0000
        # Pressure trimming params
        self.dig_P1 = 0x0000
        self.dig_P2 = 0x0000
        self.dig_P3 = 0x0000
        self.dig_P4 = 0x0000
        self.dig_P5 = 0x0000
        self.dig_P6 = 0x0000
        self.dig_P7 = 0x0000
        self.dig_P8 = 0x0000
        self.dig_P9 = 0x0000
        # Humidity trimming params
        self.dig_H1 = 0x00
        self.dig_H2 = 0x0000
        self.dig_H3 = 0x00
        self.dig_H4 = 0x0000
        self.dig_H5 = 0x0000
        self.dig_H6 = 0x00

        # Get the trimming values
        self.__read_calib()

        # Variables for compensated measurements
        self.temperature = 0x00000
        self.pressure = 0x00000
        self.humidity = 0x00000
        self.calibrated_temperature = 0x00000
        self.calibrated_pressure = 0x00000
        self.calibrated_humidity = 0x00000

        # Variables for measurement calibration
        self.calibration_temperature = 0
        self.calibration_pressure = 0
        self.calibration_humidity = 0

    #########################################
    # set bme280 operating mode             #
    #########################################
    def set_mode(self, mode=MODE_SLEEP, t_sb=t_sb_1000):
        # Writes ctrl_meas register with current temperature and pressure oversampling settings
        # Only changes the mode
        # If normal mode selected also sets the standby time in config register

        # Set class variables
        self.mode = mode
        self.t_sb = t_sb

        # If no measurements are enabled there is no point going into measurement
        if self.osrs_t + self.osrs_p + self.osrs_h == 0:
            print(
                "No measurement enabled!\nSee set_oversampling()-function to enable measurement."
            )
            return 0

        try:
            # If normal mode set also t_sb(standby time)
            if self.mode == self.MODE_NORMAL:
                # Write normal mode standby time t_sb to config register
                self.__config(t_sb, self.filter, self.spi3w_en)
                # Write mode to ctr_meas register
                self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode)
            # Otherwise just change the mode in ctrl_meas register
            else:
                self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode)

            self.last_meas = clock_gettime(CLOCK_REALTIME)
            # Everything went well return 1
            return 1
        except Exception as e:
            # e = sys.exc_info()[0]
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################################################
    # Set oversampling/enable measurement. OVRS_x0 disables the measurement #
    #########################################################################
    def set_oversampling(self, osrs_h=OVRS_x0, osrs_t=OVRS_x0, osrs_p=OVRS_x0):
        # Set oversampling variables
        self.osrs_h = osrs_h
        self.osrs_t = osrs_t
        self.osrs_p = osrs_p

        try:
            # Set humidity oversampling
            self.__ctrl_hum(self.osrs_h)
            # Set temperature and pressure oversampling
            self.__ctrl_meas(self.osrs_t, self.osrs_p, self.mode)
        except Exception as e:
            # e = sys.exc_info()[0]
            print("<p>Error: %s</p>" % e)
            return 0

        # Everything went well return 1
        return 1

    #########################################
    # Set internal IIR filter               #
    #########################################
    def set_filter(self, filter_coefficient=filter_0):
        self.filter = filter_coefficient

        try:
            # Write config register with new filter setting
            self.__config(self.t_sb, self.filter, self.spi3w_en)
            return 1
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # Set internal SPI interface            #
    #########################################
    def set_spi(self, spi3w_en=SPI_OFF):
        self.spi3w_en = spi3w_en

        try:
            # Write config register with new spi setting
            self.__config(self.t_sb, self.filter, self.spi3w_en)
            return 1
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # Reset command                         #
    #########################################
    def write_reset(self):
        register = 0xE0
        data = 0xB6  # Reset command to register, other values than 0xB6 has no effect
        r_len = 0
        delay = 10

        command = ([register, data], r_len, delay)

        try:
            self.read_write(command)
            return 1
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # read ID register                      #
    #########################################
    def read_id(self):
        register = 0xD0
        data = 0x00
        r_len = 1
        delay = 10

        command = ([register, data], r_len, delay)

        try:
            return hex(self.read_write(command)[0])
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # read STATUS register                  #
    #########################################
    def read_status(self):
        register = 0xF3
        data = 0x00
        r_len = 1
        delay = 10

        command = ([register, data], r_len, delay)

        try:
            self.status = self.read_write(command)[0]
            self.measuring = (self.status >> 3) & 0b1
            self.im_update = self.status & 0b1
            return [self.status, self.measuring, self.im_update]
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # read calibration registers            #
    #########################################
    def __read_calib(self):
        # Calibration data registers are 0x88-0xA1(25 bytes) and 0xE1-0xE7(7 bytes) total 32 bytes
        # command format ([Register, Data Bytes], Number of bytes to read, Additional sleep(ms))
        # If Number of bytes to read > 0 then read_write function reads from I2C Bus
        # Otherwise Write operation is performed.
        register1 = 0x88
        register2 = 0xE1
        data = 0x00
        r_len1 = 26
        r_len2 = 7
        delay = 10

        command1 = ([register1, data], r_len1, delay)
        command2 = ([register2, data], r_len2, delay)

        try:
            self.calib[0:26] = self.read_write(command1)
            self.calib[26:32] = self.read_write(command2)
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

        # Assign fetched data to trim parameters
        # Temperature trimming params
        # unsigned are ok, signed must be calculated with twos complement
        bytes_short = 16
        bytes_char = 8

        self.dig_T1 = (self.calib[1] << 8) + (self.calib[0] & 0xffff)
        self.dig_T2 = self.__twos_complement(
            ((self.calib[3] << 8) + self.calib[2]), bytes_short)
        self.dig_T3 = self.__twos_complement(
            (self.calib[5] << 8) + self.calib[4], bytes_short)

        # Pressure trimming params
        self.dig_P1 = ((self.calib[7] << 8) + self.calib[6]) & 0xffff
        self.dig_P2 = self.__twos_complement(
            (self.calib[9] << 8) + self.calib[8], bytes_short)
        self.dig_P3 = self.__twos_complement(
            (self.calib[11] << 8) + self.calib[10], bytes_short)
        self.dig_P4 = self.__twos_complement(
            (self.calib[13] << 8) + self.calib[12], bytes_short)
        self.dig_P5 = self.__twos_complement(
            (self.calib[15] << 8) + self.calib[14], bytes_short)
        self.dig_P6 = self.__twos_complement(
            (self.calib[17] << 8) + self.calib[16], bytes_short)
        self.dig_P7 = self.__twos_complement(
            (self.calib[19] << 8) + self.calib[18], bytes_short)
        self.dig_P8 = self.__twos_complement(
            (self.calib[21] << 8) + self.calib[20], bytes_short)
        self.dig_P9 = self.__twos_complement(
            (self.calib[23] << 8) + self.calib[22], bytes_short)

        # Humidity trimming params
        self.dig_H1 = self.calib[25] & 0xff
        self.dig_H2 = self.__twos_complement(
            (self.calib[27] << 8) + self.calib[26], bytes_short)
        self.dig_H3 = self.calib[28] & 0xff
        self.dig_H4 = self.__twos_complement(
            (self.calib[29] << 4) + (self.calib[30] & 0x0f), bytes_short)
        self.dig_H5 = self.__twos_complement(
            (self.calib[31] << 4) + ((self.calib[30] & 0xf0) >> 4),
            bytes_short)
        self.dig_H6 = self.__twos_complement(self.calib[32], bytes_char)

        # Everything went well return 1
        return 1

    #########################################
    # read raw signals registers            #
    #########################################
    def read_raw_signals(self):
        # RAW Signals memory area is 0xF7-0xFE so there is 8 bytes
        # command format ([Register, Data Bytes], Number of bytes to read, Additional sleep(ms))
        # If Number of bytes to read > 0 then read_write function reads from I2C Bus
        # Otherwise Write operation is performed.
        register = 0xF7
        data = 0x00
        r_len = 8
        delay = 10

        command = ([register, data], r_len, delay)

        try:
            self.raw_data = self.read_write(command)
            self.raw_pressure = ((
                (self.raw_data[0] << 8) + self.raw_data[1]) << 4) + (
                    (self.raw_data[2] >> 4) & 0x0f)
            self.raw_temperature = (((
                (self.raw_data[3] << 8) + self.raw_data[4]) << 4) +
                                    ((self.raw_data[5] >> 4) & 0x0f))
            self.raw_humidity = ((self.raw_data[6] << 8) + self.raw_data[7])
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

        # Everything went well return 1
        return 1

    #########################################
    # read compensated signals              #
    #########################################
    def read_compensated_signals(self):
        # Assuming that raw signals are already read
        # Compensation is performed like in datasheet appendix 8
        # 8.1 Compensation formulas in double precision floating point

        try:
            # Get Temperature t_fine value
            t_fine = self.__comp_temperature()
            self.temperature = t_fine / 5120.0  # Output value of “51.23” equals 51.23 DegC
            self.calibrated_temperature = (
                self.temperature + (0 if self.calibration_temperature is 0 else
                                    self.calibration_temperature))

            # Get pressure
            self.pressure = self.__comp_pressure(t_fine) / 100.0
            self.calibrated_pressure = (self.pressure +
                                        (0 if self.calibration_pressure is 0
                                         else self.calibration_pressure))

            # Get Humidity
            self.humidity = self.__comp_humidity(t_fine)
            self.calibrated_humidity = (self.humidity +
                                        (0 if self.calibration_humidity is 0
                                         else self.calibration_humidity))

            return 1
        except Exception as e:
            # print("Error in set_filter()")
            print("<p>Error: %s</p>" % e)
            return 0

    #########################################
    # Temperature compensation formulas     #
    # returns t_fine, because it is used in #
    # other compensation formulas           #
    #########################################
    def __comp_temperature(self):
        var1 = ((self.raw_temperature / 16384.0) -
                (self.dig_T1 / 1024.0)) * self.dig_T2
        var2 = ((((self.raw_temperature / 131072.0) - (self.dig_T1 / 8192.0)) *
                 ((self.raw_temperature / 131072.0) -
                  (self.dig_T1 / 8192.0))) * self.dig_T3)
        # t_fine = var1 + var2
        return var1 + var2

    #############################################################
    # Pressure compensation formulas                            #
    # Returns pressure in Pa as double.                         #
    # Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa #
    #############################################################
    def __comp_pressure(self, t_fine):
        var1 = (t_fine / 2.0) - 64000.0
        var2 = var1 * var1 * self.dig_P6 / 32768.0
        var2 = var2 + var1 * self.dig_P5 * 2.0
        var2 = (var2 / 4.0) + (self.dig_P4 * 65536.0)
        var1 = (self.dig_P3 * var1 * var1 / 524288.0 +
                self.dig_P2 * var1) / 524288.0
        var1 = (1.0 + var1 / 32768.0) * self.dig_P1
        if var1 == 0.0:
            return 0  # avoid exception caused by division by zero

        p = 1048576.0 - self.raw_pressure
        p = (p - (var2 / 4096.0)) * 6250.0 / var1
        var1 = self.dig_P9 * p * p / 2147483648.0
        var2 = p * self.dig_P8 / 32768.0
        p = p + (var1 + var2 + self.dig_P7) / 16.0
        return p

    ##################################################
    # Humidity compensation formulas                 #
    # Returns humidity in %rH as as double.          #
    # Output value of “46.332” represents 46.332 %rH #
    ##################################################
    def __comp_humidity(self, t_fine):
        var_h = t_fine - 76800.0
        var_h = ((self.raw_humidity - (self.dig_H4 * 64.0 +
                                       (self.dig_H5 / 16384.0 * var_h))) *
                 (self.dig_H2 / 65536.0 *
                  (1.0 + self.dig_H6 / 67108864.0 * var_h *
                   (1.0 + self.dig_H3 / 67108864.0 * var_h))))
        var_h = var_h * (1.0 - self.dig_H1 * var_h / 524288.0)
        if var_h > 100.0:
            var_h = 100.0
        elif var_h < 0.0:
            var_h = 0.0

        return var_h

    #########################################
    # write ctrl_hum register               #
    #########################################
    def __ctrl_hum(self, osrs_h=OVRS_x0):
        register = 0xF2
        r_len = 0
        delay = 10

        # Make byte to send
        # data = ((0x00 << 3) + osrs_h)
        data = osrs_h

        command = ([register, data], r_len, delay)
        self.read_write(command)

    #########################################
    # write ctrl_meas register              #
    #########################################
    def __ctrl_meas(self, osrs_t=OVRS_x0, osrs_p=OVRS_x0, mode=MODE_SLEEP):
        register = 0xF4
        r_len = 0
        delay = 10

        # Make byte to send
        data = ((((osrs_t << 3) + osrs_p) << 2) + mode)

        command = ([register, data], r_len, delay)
        self.read_write(command)

    #########################################
    # write config register                 #
    #########################################
    def __config(self, t_sb, iir_filter, spi3w_en):
        register = 0xF5
        r_len = 0
        delay = 10

        # Make byte to send
        data = ((((t_sb << 3) + iir_filter) << 2) + spi3w_en)

        command = ([register, data], r_len, delay)
        self.read_write(command)

    ##############################################################
    # set_pressure_calibration                                   #
    # level = known level from sea                               #
    # pressure =  current local pressure normalized to sea level #
    ##############################################################
    def set_pressure_calibration(self, level, pressure):
        self.calibration_pressure = (pressure - level / 8) - self.pressure

    #########################################
    # get current altitude                  #
    # pressure = current sea level pressure #
    #########################################
    def get_altitude(self, pressure):
        return (pressure - self.calibrated_pressure) * 8

    ###########################################
    # read and write data to the bme280/(I2C) #
    ###########################################
    def read_write(self, command):
        if command[1] <= 0:
            # Write to I2C-bus
            # write_i2c_block_data(address, offset, [data_bytes])
            self.bus.write_i2c_block_data(self.address, command[0][0],
                                          command[0][1:])
            sleep(command[2] / 1000)
            return 1
        else:
            # Read from I2C-Bus
            # read_i2c_block_data(address, register, number_of_data_bytes)
            return self.bus.read_i2c_block_data(self.address, command[0][0],
                                                command[1])

    #########################################
    # Twos complement calculation           #
    #########################################
    @staticmethod
    def __twos_complement(input_value, num_bits):
        """Calculates a two's complement integer from the given input value's bits."""

        mask = 2**(num_bits - 1)
        return -(input_value & mask) + (input_value & (mask - 1))
class Tsl2561:
    i2c = None

    def __init__(self, bus=I2C_SMBUS, address=I2C_ADDRESS, debug=1, pause=0.8):
            # assert(bus is not None)
            # assert(address > 0b000111 and address < 0b1111000)
            self.address = address
            self.bus = Bus(bus)
            self.pause = pause
            self.debug = debug
            self.gain  = 0
            self._bus  = bus
            self._addr = address

            ambient       = None
            IR            = None
            self._ambient = 0
            self._IR      = 0
            self._LUX     = None
            self._control(_POWER_UP)
            self._partno_revision()

    def _reverseByteOrder(self, data):
        """Reverses the byte order of an int (16-bit) or long (32-bit) value"""
        # Courtesy Vishal Sapre
        byteCount = len(hex(data)[2:].replace('L','')[::2])
        val       = 0
        for i in range(byteCount):
           val    = (val << 8) | (data & 0xff)
           data >>= 8
        return val

    def _read_byte(self, address):
        command = _CMD | address
        self.bus.read_byte_data(self.address, command)

    def _read_word(self, address,little_endian=True):
        try:
           command = _CMD | address
           result = self.bus.read_word_data(self.address, command)
           if not little_endian:
               result = ((result << 8) & 0xFF00) + (result >> 8)
           if (self.debug):
               print ("I2C: Device 0x{} returned 0x{} from reg 0x{}".format(self.address, result & 0xFFFF, reg))
           return result
       except IOError, err:
           return self.errMsg()

    def _write_byte(self, address, data):
        command = _CMD | address
        self.bus.write_byte_data(self.address, command, data)

    def _write_word(self, address, data):
        command = _CMD | _AUTO | address
        data = [(data >> 8) & 0xFF, data & 0xFF]
        self.bus.write_i2c_block_data(self.address, command, data)

    def setGain(self, gain = 1):
        """ Set the gain """
        if (gain != self.gain):
            if (gain==1):
                cmd = _CMD | _REG_TIMING
                value = 0x02
                self._write_byte(cmd, value)
                if (self.debug):
                    print ("Setting low gain")
            else:
                cmd = _CMD | _REG_TIMING
                value = 0x12
                self._write_byte(cmd, value)
                if (self.debug):
                    print ("Setting high gain")
            self.gain = gain    # Safe gain for calculation
            print('setGain...gian=',gain)
            time.sleep(self.pause)   # Pause for integration (self.pause must be bigger than integration time)

    def readWord(self, reg):
        """ Reads a word from the TSL2561 I2C device """
        try:
            wordval = self._read_word(reg)
            print ('wordval=',wordval)
            newval = self._reverseByteOrder(wordval)
            print ('newval=',newval)
            if (self.debug):
                print("I2C: Device 0x{}: returned 0x{} from reg 0x{}".format(self._addr, wordval & 0xFFFF, reg))
            return newval
        except IOError:
            print("Error accessing 0x{}: Chcekcyour I2C address".format(self._addr))
            return -1

    def readFull(self, reg = 0x8C):
        """ Read visible + IR diode from the TSL2561 I2C device """
        return self.readWord(reg)

    def readIR(self, reg = 0x8E):
        """ Reads only IR diode from the TSL2561 I2C device """
        return self.readWord(reg)

    def readLux(self, gain = 0):
        """ Grabs a lux reading either with autoranging (gain=0) or with specific gain (1, 16) """
        if (self.debug):
            print ("gain=",gain)
        if (gain == 1 or gain == 16):
            self.setGain(gain)   # Low/High Gain
            ambient = self.readFull()
            IR = self.readIR()
        elif (gain == 0):   # Auto gain
            self.setGain(16)  # First try highGain
            ambient = self.readFull()
            if (ambient < 65535):
                IR = slef.readIR()
            if (ambient >= 65535 or IR >= 65535): # Value(s) exeed(s) datarange
                self.setGain(1)  # Set low Gain
                ambient = self.readFull()
                IR = self.readIR()

        # If either sensor is saturated, no acculate lux value can be achieved.
        if (ambient == 0xffff or IR == 0xffff):
            self._LUX = None
            self._ambient = None
            self._IR = None
            return (self.ambient, self.IR, self._ambient, self._IR, self._LUX)
        if (self.gain == 1):
            self._ambient = 16 * ambient    # Scale 1x to 16x
            self._IR = 16 * IR
        else:
            self._ambient = 1 * ambient
        if (self.debug):
           print ("IR Result without scaling: ",IR)
           print ("IR Result: ", self._IR)
           print ("Ambient Result without scaling: ", ambient)
           print ("Ambient Result: ", self._ambient)

        if (self._ambient == 0):
           # Sometimes, the channel 0 returns 0 when dark ...
           self._LUX = 0.0
           return (ambient, IR, self._ambient, self._IR, self._LUX)
        
        ratio = (self._IR / float(self._ambient)) 

        if (self.debug):
            print ("ratio: ", ratio)

        if ((ratio >= 0) and (ratio <= 0.52)):
            self._LUX = (0.0315 * self._ambient) - (0.0593 * self._ambient * (ratio ** 1.4))
        elif (ratio <= 0.65):
            self._LUX = (0.0229 * self._ambient) - (0.0291 * self._IR)
        elif (ratio <= 0.80):
            self._LUX = (0.0157 * self._ambient) - (0.018 * self._IR)
        elif (ratio <= 1.3):
            self._LUX = (0.00338 * self._ambient) - (0.0026 * self._IR)
        elif (ratio > 1.3):
            self._LUX = 0

        return (ambient, IR, self._ambient, self._IR, self._LUX)
    
    def _control(self, params):
        if (params == _POWER_UP):
            print ("Power ON")
        elif (params == _POWER_DOWN):
            print ("Power OFF")
        cmd = _CMD | _REG_CONTROL | params
        self._write_byte(self._addr, cmd) # select command register and power on
        time.sleep(0.4) # Wait for 400ms to power up or power down.

    def _partno_revision(self):
        """ Read Partnumber and revision of the sensor """
        cmd = _CMD | _REG_ID
        value = self._read_byte(cmd)
        print ("value=",value)
        part = str(value)[7:4]
        if (part == "0000"):
            PartNo = "TSL2560CS"
        elif (part == "0001"):
            PartNo = "TSL2561CS"
        elif (part == "0100"):
            PartNo = "TSL2560T/FN/CL"
        else:
            PartNo = "not TSL2560 or TSL2561"
        RevNo = str(value)[3:0]
        if (self.debug):
            print ("response: ", value)
            print ("PartNo = ", PartNo)
            print ("RevNo = ", RevNo)
        return (PartNo, RevNo)
Пример #13
0
class GroveI2cColorSensorV2:
    """Driver for Grove I2C Color Sensor (TCS34725)"""
    def __init__(self, bus=None, address=0x29):
        self.address = address
        self.bus = Bus(bus)

        self.awake = False

        if self.id not in (0x44, 0x4D):
            raise ValueError('Not find a Grove I2C Color Sensor V2')

        self.set_integration_time(24)
        self.set_gain(4)

    def wakeup(self):
        enable = self._read_byte(_ENABLE)
        self._write_byte(_ENABLE, enable | _PON | _AEN)
        time.sleep(0.0024)

        self.awake = True

    def sleep(self):
        enable = self._read_byte(_ENABLE)
        self._write_byte(_ENABLE, enable & ~_PON)

        self.awake = False

    def is_awake(self):
        return self._read_byte(_ENABLE) & _PON

    def set_wait_time(self, t):
        pass

    @property
    def id(self):
        return self._read_byte(_ID)

    @property
    def integration_time(self):
        steps = 256 - self._read_byte(_ATIME)
        return steps * 2.4

    def set_integration_time(self, t):
        """Set the integration time of the sensor"""
        if t < 2.4:
            t = 2.4
        elif t > 614.4:
            t = 614.4

        steps = int(t / 2.4)
        self._integration_time = steps * 2.4
        self._write_byte(_ATIME, 256 - steps)

    @property
    def gain(self):
        """The gain control. Should be 1, 4, 16, or 60.
        """
        return _GAINS[self._read_byte(_CONTROL)]

    def set_gain(self, gain):
        if gain in _GAINS:
            self._write_byte(_CONTROL, _GAINS.index(gain))

    @property
    def raw(self):
        """Read RGBC registers
        return 16 bits red, green, blue and clear data
        """

        if not self.awake:
            self.wakeup()

        while not self._valid():
            time.sleep(0.0024)

        data = tuple(
            self._read_word(reg) for reg in (_RDATA, _GDATA, _BDATA, _CDATA))
        return data

    @property
    def rgb(self):
        """Read the RGB color detected by the sensor.  Returns a 3-tuple of
        red, green, blue component values as bytes (0-255).
        """
        r, g, b, clear = self.raw
        if clear:
            r = int(255 * r / clear)
            g = int(255 * g / clear)
            b = int(255 * b / clear)
        else:
            r, g, b = 0, 0, 0
        return r, g, b

    def _valid(self):
        """Check if RGBC is valid"""
        return self._read_byte(_STATUS) & 0x01

    def _read_byte(self, address):
        command = _CMD | address
        return self.bus.read_byte_data(self.address, command)

    def _read_word(self, address):
        command = _CMD | _AUTO | address
        return self.bus.read_word_data(self.address, command)

    def _write_byte(self, address, data):
        command = _CMD | address
        self.bus.write_byte_data(self.address, command, data)

    def _write_word(self, address, data):
        command = _CMD | _AUTO | address
        data = [(data >> 8) & 0xFF, data & 0xFF]
        self.bus.write_i2c_block_data(self.address, command, data)
Пример #14
0
class GroveOledDisplay128x64(object):
    HORIZONTAL = 0x00
    VERTICAL = 0x01
    PAGE = 0x02

    def __init__(self, bus=None, address=0x3C):
        self.bus = Bus(bus)
        self.address = address

        self.off()
        self.inverse = False
        self.mode = self.HORIZONTAL

        self.width = 128 # test
        self.height = 64 # test
        self._pages = self.height//8 # test
        self._buffer = [0]*(self.width*self._pages) # test

        self.clear()
        self.on()

    def on(self):
        self.send_command(_DISPLAY_ON)

    def off(self):
        self.send_command(_DISPLAY_OFF)

    def send_command(self, command):
        self.bus.write_byte_data(self.address, _COMMAND_MODE, command)

    def send_data(self, data):
        self.bus.write_byte_data(self.address, _DATA_MODE, data)

    def send_commands(self, commands):
        for c in commands:
            self.send_command(c)

    def clear(self):
        self.off()
        self._buffer = [0]*(self.width*self._pages)
        self.adf_display()
        self.on()
        self.set_cursor(0, 0)

    @property
    def inverse(self):
        return self._inverse

    @inverse.setter
    def inverse(self, enable):
        self.send_command(_INVERSE_DISPLAY if enable else _NORMAL_DISPLAY)
        self._inverse = enable

    @property
    def mode(self):
        return self._mode

    @mode.setter
    def mode(self, mode):
        self.send_command(0x20)
        self.send_command(mode)
        self._mode = mode

    def set_cursor(self, row, column):
        self.send_command(0xB0 + row)
        self.send_command(0x00 + (8*column & 0x0F))
        self.send_command(0x10 + ((8*column>>4)&0x0F))

    def putc(self, c):
        C_add = ord(c)
        if C_add < 32 or C_add > 127:     # Ignore non-printable ASCII characters
            c = ' '
            C_add = ord(c)

        for i in range(0, 8):
            self.send_data(BasicFont[C_add-32][i])

    def puts(self, text):
        for c in text:
            self.putc(c)

    def adf_image(self, image):
        """Set buffer to value of Python Imaging Library image.  The image should
        be in 1 bit mode and a size equal to the display size.
        """
        if image.mode != '1':
            raise ValueError('Image must be in mode 1.')
        imwidth, imheight = image.size
        if imwidth != 128 or imheight != 64:
            raise ValueError('Image must be same dimensions as display (128x64).')
        # Grab all the pixels from the image, faster than getpixel.
        pix = image.load()
        # Iterate through the memory pages
        index = 0
        for page in range(self._pages):
            # Iterate through all x axis columns.
            for x in range(self.width):
                # Set the bits for the column of pixels at the current position.
                bits = 0
                # Don't use range here as it's a bit slow
                for bit in [0, 1, 2, 3, 4, 5, 6, 7]:
                    bits = bits << 1
                    bits |= 0 if pix[(x, page*8+7-bit)] == 0 else 1
                # Update buffer byte and increment to next byte.
                self._buffer[index] = bits
                index += 1

    def adf_display(self):
        """Write display buffer to physical display."""
        # self.command(SSD1306_COLUMNADDR)
        # self.command(0)              # Column start address. (0 = reset)
        # self.command(self.width-1)   # Column end address.
        # self.command(SSD1306_PAGEADDR)
        # self.command(0)              # Page start address. (0 = reset)
        # self.command(self._pages-1)  # Page end address.
        # Write buffer data.
        for i in range(0, len(self._buffer), 16):
            control = 0x40   # Co = 0, DC = 0
            #self._i2c.writeList(control, self._buffer[i:i+16])
            #self._bus.write_i2c_block_data(self._address, register, data)
            #self.bus.write_byte_data(self.address, _DATA_MODE, data)
            self.bus.write_i2c_block_data(self.address, _DATA_MODE, self._buffer[i:i+16])


    def show_image(self, image):
        #im = image  #Image.open(image)
        #bw = im.convert('1')
        pixels = np.array(image.getdata())
        #pixels = image.load()
        page_size = 128 * 8
        self.set_cursor(0, 0)
        # iterate through pages
        for page in range(8):
            start = page_size * page
            end = start + page_size
            # iterate through x-axis columns
            for i in range(start, start + 128):
                data = np.packbits(pixels[i:end:128][::-1])[0]
                self.send_data(data)