def test_get_register():
    bus = MockSMBus(1)
    bus.regs[0:3] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]
    device = Device([0x00, 0x01],
                    i2c_dev=bus,
                    registers=(
                        Register('test24',
                                 0x00,
                                 fields=(BitField('test', 0xFFF), ),
                                 bit_width=24),
                        Register('test32',
                                 0x00,
                                 fields=(BitField('test', 0xFFF), ),
                                 bit_width=32),
                        Register('test48',
                                 0x00,
                                 fields=(BitField('test', 0xFFF), ),
                                 bit_width=48),
                    ))

    assert device.get_register('test24') == 0xAABBCC

    assert device.get_register('test32') == 0xAABBCCDD

    assert device.get_register('test48') == 0xAABBCCDDEEFF
Beispiel #2
0
    def __init__(self, i2c_addr=0x45, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False

        self.shunt_resistor_value = 0.005  # value in ohms
        self.shunt_voltage_lsb = 0.00001   # 10 uV per LSB
        self.bus_voltage_lsb = 0.004       # 4mV per LSB

        self._ina220 = Device([self._i2c_addr], i2c_dev=self._i2c_dev, bit_width=8, registers=(
            Register('CONFIG', 0x00, fields=(
                BitField('reset', 0b1000000000000000),
                BitField('bus_voltage_range', 0b0010000000000000),
                BitField('pga_gain', 0b0001100000000000, adapter=LookupAdapter({
                    '40': 0b00,
                    '80': 0b01,
                    '160': 0b10,
                    '320': 0b11
                }), bit_width=16),
                BitField('bus_adc', 0b0000011110000000, adapter=sadc_badc_adapter, bit_width=16),
                BitField('shunt_adc', 0b0000000001111000, adapter=sadc_badc_adapter, bit_width=16),
                BitField('mode', 0b0000000000000111, adapter=LookupAdapter({
                    'power_down': 0b000,
                    'shunt_voltage_triggered': 0b001,
                    'bus_voltage_triggered': 0b010,
                    'shunt_and_bus_triggered': 0b011,
                    'adc_off': 0b100,
                    'shunt_voltage_continuous': 0b101,
                    'bus_voltage_continuous': 0b110,
                    'shunt_and_bus_continuous': 0b111
                }), bit_width=16),

            )),

            Register('SHUNT_VOLTAGE', 0x01, fields=(
                BitField('reading', 0xFFFF),
            ), bit_width=16, read_only=True),

            Register('BUS_VOLTAGE', 0x02, fields=(
                BitField('reading', 0b1111111111111000),
                BitField('conversion_ready', 0b0000000000000010),
                BitField('math_overflow_flag', 0b0000000000000001)

            ), bit_width=16, read_only=True),

            Register('POWER', 0x03, fields=(
                BitField('reading', 0xFFFF),
            ), bit_width=16, read_only=True),

            Register('CURRENT', 0x04, fields=(
                BitField('reading', 0xFFFF),
            ), bit_width=16, read_only=True),

            Register('CALIBARTION', 0x05, fields=(
                BitField('reading', 0xFFFF),
            ), bit_width=16, read_only=True),
        ))

        self._configuration = self.get_configuration()
def test_set_regs():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))
    device.set('test', test=123)

    assert device.get('test').test == 123

    assert bus.regs[0] == 123
def test_get_set_field_overflow():
    bus = MockSMBus(1)
    device = Device([0x00, 0x01],
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))

    device.set_field('test', 'test', 9999999)

    assert device.get_field('test', 'test') == 127

    assert bus.regs[0] == 127
def test_missing_regiser():
    bus = MockSMBus(1)
    device = Device(
        [0x00, 0x01],
        i2c_dev=bus,
        registers=(
            Register(
                'test',
                0x00,
                fields=(
                    BitFlag('test', 6),  # Sixth bit from the right
                )), ))

    with pytest.raises(KeyError):
        device.get_register('foo')
def test_field_name_in_adapter_error():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test',
                                                         0xFF00,
                                                         adapter=LookupAdapter(
                                                             {'x': 1})), ),
                                        bit_width=16), ))

    with pytest.raises(ValueError) as e:
        reg = device.get('test')
        assert 'test' in e
        del reg
Beispiel #7
0
def test_smbus_io():
    sys.modules['smbus'] = SMBus
    device = Device(0x00,
                    i2c_dev=None,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))
    del device
Beispiel #8
0
    def __init__(self, i2c_addr=I2C_ADDR1, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._drv8830 = Device(
            [I2C_ADDR1, I2C_ADDR2, I2C_ADDR3, I2C_ADDR4],
            i2c_dev=self._i2c_dev,
            registers=(
                Register(
                    'CONTROL',
                    0x00,
                    fields=(
                        BitField('voltage',
                                 0b11111100,
                                 adapter=VoltageAdapter()),  # vset
                        BitField('out2', 0b00000010),  # in2
                        BitField('out1', 0b00000001),  # in1
                        BitField(
                            'direction',
                            0b00000011,
                            adapter=LookupAdapter({  # both in2 and in1 :D
                                'coast': 0b00,
                                'reverse': 0b01,
                                'forward': 0b10,
                                'brake': 0b11
                            })))),
                Register(
                    'FAULT',
                    0x01,
                    fields=(
                        BitField(
                            'clear', 0b10000000
                        ),  # Clears fault status bits when written to 1
                        BitField('current_limit', 0b00010000
                                 ),  # Fault caused by external current limit
                        BitField(
                            'over_temperature', 0b00001000
                        ),  # Fault caused by over-temperature condition
                        BitField('under_voltage', 0b00000100
                                 ),  # Fault caused by undervoltage lockout
                        BitField(
                            'over_current',
                            0b00000010),  # Fault caused by overcurrent event
                        BitField('fault', 0b00000001)  # Fault condition exists
                    ))))

        self._drv8830.select_address(self._i2c_addr)
def test_get_regs():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(
                                            BitField('test', 0xFF00),
                                            BitField('monkey', 0x00FF),
                                        ),
                                        bit_width=16), ))
    device.set('test', test=0x66, monkey=0x77)

    reg = device.get('test')
    reg.test == 0x66
    reg.monkey == 0x77

    assert bus.regs[0] == 0x66
    assert bus.regs[1] == 0x77
Beispiel #10
0
class PCA9554A:
    def __init__(self, i2c_addr=0x38, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False
        # Device definition
        self._pca9554a = Device(
            self._i2c_addr,
            i2c_dev=self._i2c_dev,
            bit_width=8,
            registers=(
                Register('INPUT',
                         0x00,
                         fields=(BitField('value', 0xFF),
                                 BitField('switch', 0b00001000),
                                 BitField('led', 0b00000001))),
                Register('OUTPUT',
                         0x01,
                         fields=(BitField('value', 0xFF),
                                 BitField('switch', 0b00001000),
                                 BitField('led', 0b00000001))),
                Register('INVERT',
                         0x02,
                         fields=(BitField('value', 0xFF),
                                 BitField('switch', 0b00001000),
                                 BitField('led', 0b00000001))),
                Register('CONFIG',
                         0x03,
                         fields=(BitField('value', 0xFF),
                                 BitField('switch', 0b00001000),
                                 BitField('led', 0b00000001))),
            ))
        #  Set IO configuration for driving switch and LED
        self._pca9554a.set('OUTPUT', switch=0, led=1)
        self._pca9554a.set('CONFIG', switch=0, led=0)
        self.led_enable = True
        self.switch_enabled = True
        self.led_status = False
        self.switch_status = False
Beispiel #11
0
def test_adapters():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register(
                        'adapter',
                        0x01,
                        fields=(BitField('test',
                                         0xFFFF,
                                         adapter=U16ByteSwapAdapter()), )), ))

    device.adapter.set_test(0xFF00)

    assert device.adapter.get_test() == 0xFF00

    assert bus.regs[0:2] == [0x00, 0xFF]
Beispiel #12
0
def test_address_select():
    bus = MockSMBus(1)
    device = Device([0x00, 0x01],
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))

    assert device.get_addresses() == [0x00, 0x01]
    assert device.select_address(0x01) is True
    with pytest.raises(ValueError):
        device.select_address(0x02)

    assert device.next_address() == 0x00
    assert device.next_address() == 0x01
Beispiel #13
0
def test_bitflag():
    bus = MockSMBus(1)
    device = Device(
        [0x00, 0x01],
        i2c_dev=bus,
        registers=(
            Register(
                'test',
                0x00,
                fields=(
                    BitFlag('test', 6),  # Sixth bit from the right
                )), ))

    device.test.set_test(True)

    assert bus.regs[0] == 0b01000000

    device.test.set_test(False)

    assert bus.regs[0] == 0b00000000
Beispiel #14
0
def test_register_locking():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))

    device.test.set_test(77)
    device.lock_register('test')

    bus.regs[0] = 11
    assert device.test.get_test() == 77

    device.unlock_register('test')
    assert device.test.get_test() == 11
Beispiel #15
0
def test_register_proxy():
    bus = MockSMBus(1)
    device = Device(0x00,
                    i2c_dev=bus,
                    registers=(Register('test',
                                        0x00,
                                        fields=(BitField('test', 0xFF), )), ))
    device.test.set_test(123)

    assert device.test.get_test() == 123

    assert bus.regs[0] == 123

    with device.test as test:
        test.set_test(77)
        test.write()

    assert device.test.get_test() == 77

    assert bus.regs[0] == 77

    assert device.test.read() == 77
def test_register_proxy():
    """This API pattern has been depricated in favour of set/get."""
    bus = MockSMBus(1)
    device = Device(0x00, i2c_dev=bus, registers=(
        Register('test', 0x00, fields=(
            BitField('test', 0xFF),
        )),
    ))
    device.test.set_test(123)

    assert device.test.get_test() == 123

    assert bus.regs[0] == 123

    with device.test as test:
        test.set_test(77)
        test.write()

    assert device.test.get_test() == 77

    assert bus.regs[0] == 77

    assert device.test.read() == 77
Beispiel #17
0
class BH1745:
    """BH1745 colour sensor."""

    def __init__(self, i2c_addr=0x38, i2c_dev=None):
        """Initialise sensor.

        :param i2c_addr: i2c address of sensor
        :param i2c_dev: SMBus-compatible instance

        """
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False
        # Device definition
        self._bh1745 = Device(I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=(
            # Part ID should be 0b001011 or 0x0B
            Register('SYSTEM_CONTROL', 0x40, fields=(
                BitField('sw_reset', 0b10000000),
                BitField('int_reset', 0b01000000),
                BitField('part_id', 0b00111111, read_only=True)
            )),

            Register('MODE_CONTROL1', 0x41, fields=(
                BitField('measurement_time_ms', 0b00000111, adapter=LookupAdapter({
                    160: 0b000,
                    320: 0b001,
                    640: 0b010,
                    1280: 0b011,
                    2560: 0b100,
                    5120: 0b101
                })),
            )),

            Register('MODE_CONTROL2', 0x42, fields=(
                BitField('valid', 0b10000000, read_only=True),
                BitField('rgbc_en', 0b00010000),
                BitField('adc_gain_x', 0b00000011, adapter=LookupAdapter({
                    1: 0b00, 2: 0b01, 16: 0b10}))
            )),

            Register('MODE_CONTROL3', 0x44, fields=(
                BitField('on', 0b11111111, adapter=LookupAdapter({True: 2, False: 0})),
            )),

            Register('COLOUR_DATA', 0x50, fields=(
                BitField('red', 0xFFFF000000000000, adapter=U16ByteSwapAdapter()),
                BitField('green', 0x0000FFFF00000000, adapter=U16ByteSwapAdapter()),
                BitField('blue', 0x00000000FFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('clear', 0x000000000000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=64, read_only=True),

            Register('DINT_DATA', 0x58, fields=(
                BitField('data', 0xFFFF, adapter=U16ByteSwapAdapter()),
            ), bit_width=16),

            Register('INTERRUPT', 0x60, fields=(
                BitField('status', 0b10000000, read_only=True),
                BitField('latch', 0b00010000, adapter=LookupAdapter({0: 1, 1: 0})),
                BitField('source', 0b00001100, read_only=True, adapter=LookupAdapter({
                    'red': 0b00,
                    'green': 0b01,
                    'blue': 0b10,
                    'clear': 0b11
                })),
                BitField('enable', 0b00000001)
            )),

            # 00: Interrupt status is toggled at each measurement end
            # 01: Interrupt status is updated at each measurement end
            # 10: Interrupt status is updated if 4 consecutive threshold judgements are the same
            # 11: Blah blah ditto above except for 8 consecutive judgements
            Register('PERSISTENCE', 0x61, fields=(
                BitField('mode', 0b00000011, adapter=LookupAdapter({
                    'toggle': 0b00,
                    'update': 0b01,
                    'update_on_4': 0b10,
                    'update_on_8': 0b11
                })),
            )),

            # High threshold defaults to 0xFFFF
            # Low threshold defaults to 0x0000
            Register('THRESHOLD', 0x62, fields=(
                BitField('high', 0xFFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('low', 0x0000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=32),

            # Default MANUFACTURER ID is 0xE0h
            Register('MANUFACTURER', 0x92, fields=(
                BitField('id', 0xFF),
            ), read_only=True, volatile=False)
        ))

        self._bh1745.select_address(self._i2c_addr)

        # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
        # Iterate through all register fields and export their lookup tables to constants
        for register in self._bh1745.registers:
            register = self._bh1745.registers[register]
            for field in register.fields:
                field = register.fields[field]
                if isinstance(field.adapter, LookupAdapter):
                    for key in field.adapter.lookup_table:
                        name = 'BH1745_{register}_{field}_{key}'.format(
                            register=register.name,
                            field=field.name,
                            key=key
                        ).upper()
                        globals()[name] = key

        """
        Approximate compensation for the spectral response performance curves
        """
        self._channel_compensation = (2.2, 1.0, 1.8, 10.0)
        self._enable_channel_compensation = True

    # Public API methods
    def ready(self):
        """Return true if setup has been successful."""
        return self._is_setup

    def setup(self, i2c_addr=None, timeout=BH1745_RESET_TIMEOUT_SEC):
        """Set up the bh1745 sensor.

        :param i2c_addr: Optional i2c_addr to switch to

        """
        if self._is_setup:
            return True

        if timeout <= 0:
            raise ValueError('Device timeout period must be greater than 0')

        if i2c_addr is not None:
            self._bh1745.select_address(i2c_addr)

        try:
            self._bh1745.get('SYSTEM_CONTROL')
        except IOError:
            raise RuntimeError('BH1745 not found: IO error attempting to query device!')

        if self._bh1745.get('SYSTEM_CONTROL').part_id != 0b001011 or self._bh1745.get('MANUFACTURER').id != 0xE0:
            raise RuntimeError('BH1745 not found: Manufacturer or Part ID mismatch!')

        self._is_setup = True

        self._bh1745.set('SYSTEM_CONTROL', sw_reset=1)

        t_start = time.time()

        pending_reset = True

        while time.time() - t_start < timeout:
            if not self._bh1745.get('SYSTEM_CONTROL').sw_reset:
                pending_reset = False
                break
            time.sleep(0.01)

        if pending_reset:
            raise BH1745TimeoutError('Timeout waiting for BH1745 to reset.')

        self._bh1745.set('SYSTEM_CONTROL', int_reset=0)
        self._bh1745.set('MODE_CONTROL1', measurement_time_ms=320)
        self._bh1745.set('MODE_CONTROL2', adc_gain_x=1, rgbc_en=1)
        self._bh1745.set('MODE_CONTROL3', on=1)
        self._bh1745.set('THRESHOLD', low=0xFFFF, high=0x0000)
        self._bh1745.set('INTERRUPT', latch=1)

        time.sleep(0.320)

    def set_measurement_time_ms(self, time_ms):
        """Set the measurement time in milliseconds.

        :param time_ms: The time in milliseconds: 160, 320, 640, 1280, 2560, 5120

        """
        self.setup()
        self._bh1745.set('MODE_CONTROL1', measurement_time_ms=time_ms)

    def set_adc_gain_x(self, gain_x):
        """Set the ADC gain multiplier.

        :param gain_x: Must be either 1, 2 or 16

        """
        self.setup()
        self._bh1745.set('MODE_CONTROL2', adc_gain_x=gain_x)

    def set_leds(self, state):
        """Toggle the onboard LEDs.

        :param state: Either 1 for on, or 0 for off

        """
        self.setup()
        self._bh1745.set('INTERRUPT', enable=1 if state else 0)

    def set_channel_compensation(self, r, g, b, c):
        """Set the channel compensation scale factors.

        :param r: multiplier for red channel
        :param g: multiplier for green channel
        :param b: multiplier for blue channel
        :param c: multiplier for clear channel

        If you intend to measure a particular class of objects, say a set of matching wooden blocks with similar reflectivity and paint finish
        you should calibrate the channel compensation until you see colour values that broadly represent the colour of the objects you're testing.

        The default values were derived by testing a set of 5 Red, Green, Blue, Yellow and Orange wooden blocks.

        These scale factors are applied in `get_rgbc_raw` right after the raw values are read from the sensor.

        """
        self._channel_compensation = (r, g, b, c)

    def enable_white_balance(self, enable):
        """Enable scale compensation for the channels.

        :param enable: True to enable, False to disable

        See: `set_channel_compensation` for details.

        """
        self._enable_channel_compensation = True if enable else False

    def get_rgbc_raw(self):
        """Return the raw Red, Green, Blue and Clear readings."""
        self.setup()
        colour_data = self._bh1745.get('COLOUR_DATA')
        r, g, b, c = colour_data.red, colour_data.green, colour_data.blue, colour_data.clear

        if self._enable_channel_compensation:
            cr, cg, cb, cc = self._channel_compensation
            r, g, b, c = r * cr, g * cg, b * cb, c * cc

        return (r, g, b, c)

    def get_rgb_clamped(self):
        """Return an RGB value scaled against max(r, g, b).

        This will clamp/saturate one of the colour channels, providing a clearer idea
        of what primary colour an object is most likely to be.

        However the resulting colour reading will not be accurate for other purposes.

        """
        r, g, b, c = self.get_rgbc_raw()

        div = max(r, g, b)

        if div > 0:
            r, g, b = [int((x / float(div)) * 255) for x in (r, g, b)]
            return (r, g, b)

        return (0, 0, 0)

    def get_rgb_scaled(self):
        """Return an RGB value scaled against the clear channel."""
        r, g, b, c = self.get_rgbc_raw()

        if c > 0:
            r, g, b = [min(255, int((x / float(c)) * 255)) for x in (r, g, b)]
            return (r, g, b)

        return (0, 0, 0)
Beispiel #18
0
class LSM303D:
    def __init__(self, i2c_addr=0x1D, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._lsm303d = Device(
            [0x1D, 0x1E],
            i2c_dev=self._i2c_dev,
            bit_width=8,
            registers=(
                Register('TEMPERATURE',
                         0x05 | 0x80,
                         fields=(BitField('temperature',
                                          0xFFFF,
                                          adapter=TemperatureAdapter()), ),
                         bit_width=16),

                # Magnetometer interrupt status
                Register('MAGNETOMETER_STATUS',
                         0x07,
                         fields=(
                             BitField('xdata', 0b00000001),
                             BitField('ydata', 0b00000010),
                             BitField('zdata', 0b00000100),
                             BitField('data', 0b00001000),
                             BitField('xoverrun', 0b00010000),
                             BitField('yoverrun', 0b00100000),
                             BitField('zoverrun', 0b01000000),
                             BitField('overrun', 0b10000000),
                         )),
                Register('MAGNETOMETER',
                         0x08 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('WHOAMI', 0x0F, fields=(BitField('id', 0xFF), )),
                Register(
                    'MAGNETOMETER_INTERRUPT',
                    0x12,
                    fields=(
                        BitField('enable', 0b00000001),
                        BitField('4d', 0b00000010),
                        BitField('latch', 0b00000100),
                        BitField(
                            'polarity',
                            0b00001000),  # 0 = active-low, 1 = active-high
                        BitField('pin_config',
                                 0b00010000),  # 0 = push-pull, 1 = open-drain
                        BitField('z_enable', 0b00100000),
                        BitField('y_enable', 0b01000000),
                        BitField('x_enable', 0b10000000),
                    )),
                Register('MAGNETOMETER_INTERRUPT_SOURCE',
                         0x13,
                         fields=(
                             BitField('event', 0b00000001),
                             BitField('overflow', 0b00000010),
                             BitField('z_negative', 0b00000100),
                             BitField('y_negative', 0b00001000),
                             BitField('x_negative', 0b00010000),
                             BitField('z_positive', 0b00100000),
                             BitField('y_positive', 0b01000000),
                             BitField('x_positive', 0b10000000),
                         )),
                Register('MAGNETOMETER_INTERRUPT_THRESHOLD',
                         0x14 | 0x80,
                         fields=(BitField('threshold',
                                          0xFFFF,
                                          adapter=U16ByteSwapAdapter()), ),
                         bit_width=16),
                Register('MAGNETOMETER_OFFSET',
                         0x16 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('HP_ACCELEROMETER_REFERENCE',
                         0x1c | 0x80,
                         fields=(
                             BitField('x', 0xFF0000),
                             BitField('y', 0x00FF00),
                             BitField('z', 0x0000FF),
                         ),
                         bit_width=8 * 3),
                Register('CONTROL0',
                         0x1f,
                         fields=(
                             BitField('int2_high_pass', 0b00000001),
                             BitField('int1_high_pass', 0b00000010),
                             BitField('click_high_pass', 0b00000100),
                             BitField('fifo_threshold', 0b00100000),
                             BitField('fifo_enable', 0b01000000),
                             BitField('reboot_memory', 0b10000000),
                         )),
                Register('CONTROL1',
                         0x20,
                         fields=(
                             BitField('accel_x_enable', 0b00000001),
                             BitField('accel_y_enable', 0b00000010),
                             BitField('accel_z_enable', 0b00000100),
                             BitField('block_data_update', 0b00001000),
                             BitField('accel_data_rate_hz',
                                      0b11110000,
                                      adapter=LookupAdapter({
                                          0: 0,
                                          3.125: 0b0001,
                                          6.25: 0b0010,
                                          12.5: 0b0011,
                                          25: 0b0100,
                                          50: 0b0101,
                                          100: 0b0110,
                                          200: 0b0111,
                                          400: 0b1000,
                                          800: 0b1001,
                                          1600: 0b1010
                                      })),
                         )),
                Register('CONTROL2',
                         0x21,
                         fields=(
                             BitField('serial_interface_mode', 0b00000001),
                             BitField('accel_self_test', 0b00000010),
                             BitField('accel_full_scale_g',
                                      0b00111000,
                                      adapter=LookupAdapter({
                                          2: 0b000,
                                          4: 0b001,
                                          6: 0b010,
                                          8: 0b011,
                                          16: 0b100
                                      })),
                             BitField('accel_antialias_bw_hz',
                                      0b11000000,
                                      adapter=LookupAdapter({
                                          50: 0b11,
                                          362: 0b10,
                                          194: 0b01,
                                          773: 0b00
                                      })),
                         )),

                # Known in the datasheet as CTRL3
                Register('INTERRUPT1',
                         0x22,
                         fields=(
                             BitField('enable_fifo_empty', 0b00000001),
                             BitField('enable_accel_dataready', 0b00000010),
                             BitField('enable_accelerometer', 0b00000100),
                             BitField('enable_magnetometer', 0b00001000),
                             BitField('enable_ig2', 0b00010000),
                             BitField('enable_ig1', 0b00100000),
                             BitField('enable_click', 0b01000000),
                             BitField('enable_boot', 0b10000000),
                         )),

                # Known in the datasheet as CTRL4
                Register('INTERRUPT2',
                         0x23,
                         fields=(
                             BitField('enable_fifo', 0b00000001),
                             BitField('enable_fifo_overrun', 0b00000010),
                             BitField('enable_mag_dataready', 0b00000100),
                             BitField('enable_accel_dataready', 0b00001000),
                             BitField('enable_magnetometer', 0b00010000),
                             BitField('enable_ig2', 0b00100000),
                             BitField('enable_ig1', 0b01000000),
                             BitField('enable_click', 0b10000000),
                         )),
                Register('CONTROL5',
                         0x24,
                         fields=(
                             BitField('latch_int1', 0b00000001),
                             BitField('latch_int2', 0b00000010),
                             BitField('mag_data_rate_hz',
                                      0b00011100,
                                      adapter=LookupAdapter({
                                          3.125: 0b000,
                                          6.25: 0b001,
                                          12.5: 0b010,
                                          25: 0b011,
                                          50: 0b100,
                                          100: 0b101,
                                      })),
                             BitField('mag_resolution', 0b01100000),
                             BitField('enable_temperature', 0b10000000),
                         )),
                Register('CONTROL6',
                         0x25,
                         fields=(BitField('mag_full_scale_gauss',
                                          0b01100000,
                                          adapter=LookupAdapter({
                                              2: 0b00,
                                              4: 0b01,
                                              8: 0b10,
                                              12: 0b11
                                          })), )),
                Register(
                    'CONTROL7',
                    0x26,
                    fields=(
                        BitField('mag_mode',
                                 0b00000011,
                                 adapter=LookupAdapter({
                                     'continuous': 0b00,
                                     'single': 0b01,
                                     'off': 0b10
                                 })),
                        BitField('mag_lowpowermode', 0b00000100),
                        BitField('temperature_only', 0b00010000),
                        BitField('filter_accel', 0b00100000),
                        BitField('high_pass_mode_accel',
                                 0b11000000),  # See page 39 of lsm303d.pdf
                    )),

                # Accelerometer interrupt status register
                Register('ACCELEROMETER_STATUS',
                         0x27,
                         fields=(BitField('xdata', 0b00000001),
                                 BitField('ydata', 0b00000010),
                                 BitField('zdata', 0b00000100),
                                 BitField('data', 0b00001000),
                                 BitField('xoverrun', 0b00010000),
                                 BitField('yoverrun', 0b00100000),
                                 BitField('zoverrun', 0b01000000),
                                 BitField('overrun', 0b10000000))),

                # X/Y/Z values from accelerometer
                Register('ACCELEROMETER',
                         0x28 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),

                # FIFO control register
                Register('FIFO_CONTROL',
                         0x2e,
                         fields=(
                             BitField('mode', 0b11100000),
                             BitField('threshold', 0b00011111),
                         )),

                # FIFO status register
                Register(
                    'FIFO_STATUS',
                    0x2f,
                    fields=(
                        BitField('threshold_exceeded', 1 << 7),
                        BitField('overrun', 1 << 6),
                        BitField('empty', 1 << 5),
                        BitField('unread_levels', 0b00011111
                                 ),  # Current number of unread FIFO levels
                    )),

                # 0x30: Internal interrupt generator 1: configuration register
                # 0x31: Internal interrupt generator 1: status register
                # 0x32: Internal interrupt generator 1: threshold register
                # 0x33: Internal interrupt generator 1: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x30
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x31
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x32
                        BitField('threshold', 0xff << 8),
                        # 0x33
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x34: Internal interrupt generator 2: configuration register
                # 0x35: Internal interrupt generator 2: status register
                # 0x36: Internal interrupt generator 2: threshold register
                # 0x37: Internal interrupt generator 2: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x34
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x35
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x36
                        BitField('threshold', 0xff << 8),
                        # 0x37
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x38: Click: configuration register
                # 0x39: Click: status register
                # 0x3A: Click: threshold register
                # 0x3B: Click: time limit register
                # 0x3C: Click: time latency register
                # 0x3D: Click: time window register
                Register(
                    'CLICK',
                    0x38 | 0x80,
                    fields=(
                        # 0x38
                        # bits 1 << 47 and 1 << 46 are unimplemented
                        BitField('z_doubleclick_enable', 1 << 45),
                        BitField('z_click_enable', 1 << 44),
                        BitField('y_doubleclick_enable', 1 << 43),
                        BitField('y_click_enable', 1 << 42),
                        BitField('x_doubleclick_enable', 1 << 41),
                        BitField('x_click_enable', 1 << 40),
                        # 0x39
                        # bit 1 << 39 is unimplemented
                        BitField('interrupt_enable', 1 << 38),
                        BitField('doubleclick_enable', 1 << 37),
                        BitField('click_enable', 1 << 36),
                        BitField(
                            'sign', 1 <<
                            35),  # 0 positive detection, 1 negative detection
                        BitField('z', 1 << 34),
                        BitField('y', 1 << 33),
                        BitField('x', 1 << 32),
                        # 0x3A
                        BitField('threshod', 0xFF << 24),
                        # 0x3B
                        BitField('time_limit', 0xFF << 16),
                        # 0x3C
                        BitField('time_latency', 0xFF << 8),
                        # 0x3D
                        BitField('time_window', 0xFF),
                    ),
                    bit_width=8 * 6),

                # Controls the threshold and duration of returning to sleep mode
                Register(
                    'ACT',
                    0x3e | 0x80,
                    fields=(
                        BitField('threshold', 0xFF00),  # 1 LSb = 16mg
                        BitField('duration',
                                 0x00FF)  # (duration + 1) * 8/output_data_rate
                    ),
                    bit_width=16)))

        self._is_setup = False

        self._accel_full_scale_g = 2
        self._mag_full_scale_guass = 2

    def set_accel_full_scale_g(self, scale):
        """Set the full scale range for the accelerometer in g

        :param scale: One of 2, 4, 6, 8 or 16 g

        """
        self._accel_full_scale_g = scale
        with self._lsm303d.CONTROL2 as CONTROL2:
            CONTROL2.set_accel_full_scale_g(self._accel_full_scale_g)
            CONTROL2.write()

    def set_mag_full_scale_guass(self, scale):
        """Set the full scale range for the magnetometer in guass

        :param scale: One of 2, 4, 8 or 12 guass

        """
        self._mag_full_scale_guass = scale
        with self._lsm303d.CONTROL6 as CONTROL6:
            CONTROL6.set_mag_full_scale_gauss(scale)  # +-2
            CONTROL6.write()

    def setup(self):
        if self._is_setup:
            return
        self._is_setup = True

        self._lsm303d.select_address(self._i2c_addr)

        try:
            if self._lsm303d.WHOAMI.get_id() != 0x49:
                raise RuntimeError(
                    "Unable to find lsm303d on 0x{:02x}, WHOAMI returned {:02x}"
                    .format(self._i2c_addr, self._lsm303d.WHOAMI.get_id()))
        except IOError:
            raise RuntimeError(
                "Unable to find lsm303d on 0x{:02x}, IOError".format(
                    self._i2c_addr))

        with self._lsm303d.CONTROL1 as CONTROL1:
            CONTROL1.set_accel_x_enable(1)
            CONTROL1.set_accel_y_enable(1)
            CONTROL1.set_accel_z_enable(1)
            CONTROL1.set_accel_data_rate_hz(50)
            CONTROL1.write()

        self.set_accel_full_scale_g(2)

        with self._lsm303d.INTERRUPT1 as INT1:
            INT1.set_enable_fifo_empty(0)
            INT1.set_enable_accel_dataready(0)
            INT1.set_enable_accelerometer(0)
            INT1.set_enable_magnetometer(0)
            INT1.set_enable_ig2(0)
            INT1.set_enable_ig1(0)
            INT1.set_enable_click(0)
            INT1.set_enable_boot(0)
            INT1.write()

        with self._lsm303d.INTERRUPT2 as INT2:
            INT2.set_enable_fifo(0)
            INT2.set_enable_fifo_overrun(0)
            INT2.set_enable_mag_dataready(0)
            INT2.set_enable_accel_dataready(0)
            INT2.set_enable_magnetometer(0)
            INT2.set_enable_ig2(0)
            INT2.set_enable_ig1(0)
            INT2.set_enable_click(0)
            INT2.write()

        with self._lsm303d.CONTROL5 as CONTROL5:
            CONTROL5.set_mag_data_rate_hz(50)
            CONTROL5.set_enable_temperature(1)
            CONTROL5.write()

        self.set_mag_full_scale_guass(2)

        with self._lsm303d.CONTROL7 as CONTROL7:
            CONTROL7.set_mag_mode('continuous')
            CONTROL7.write()

    def magnetometer(self):
        """Return magnetometer x, y and z readings.

        These readings are given in guass and should be +/- the given mag_full_scale_guass value.

        """
        self.setup()
        with self._lsm303d.MAGNETOMETER as M:
            x, y, z = M.get_x(), M.get_y(), M.get_z()
            x, y, z = [(p / 32676.0) * self._mag_full_scale_guass
                       for p in (x, y, z)]
            return x, y, z

    def accelerometer(self):
        """Return acelerometer x, y and z readings.

        These readings are given in g annd should be +/- the given accel_full_scale_g value.

        """
        self.setup()
        with self._lsm303d.ACCELEROMETER as A:
            x, y, z = A.get_x(), A.get_y(), A.get_z()
            x, y, z = [(p / 32767.0) * self._accel_full_scale_g
                       for p in (x, y, z)]
            return x, y, z

    def temperature(self):
        """Return the temperature"""
        self.setup()
        return self._lsm303d.TEMPERATURE.get_temperature()
Beispiel #19
0
    def __init__(self, i2c_addr=0x1D, i2c_dev=None):
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._lsm303d = Device(
            [0x1D, 0x1E],
            i2c_dev=self._i2c_dev,
            bit_width=8,
            registers=(
                Register('TEMPERATURE',
                         0x05 | 0x80,
                         fields=(BitField('temperature',
                                          0xFFFF,
                                          adapter=TemperatureAdapter()), ),
                         bit_width=16),

                # Magnetometer interrupt status
                Register('MAGNETOMETER_STATUS',
                         0x07,
                         fields=(
                             BitField('xdata', 0b00000001),
                             BitField('ydata', 0b00000010),
                             BitField('zdata', 0b00000100),
                             BitField('data', 0b00001000),
                             BitField('xoverrun', 0b00010000),
                             BitField('yoverrun', 0b00100000),
                             BitField('zoverrun', 0b01000000),
                             BitField('overrun', 0b10000000),
                         )),
                Register('MAGNETOMETER',
                         0x08 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('WHOAMI', 0x0F, fields=(BitField('id', 0xFF), )),
                Register(
                    'MAGNETOMETER_INTERRUPT',
                    0x12,
                    fields=(
                        BitField('enable', 0b00000001),
                        BitField('4d', 0b00000010),
                        BitField('latch', 0b00000100),
                        BitField(
                            'polarity',
                            0b00001000),  # 0 = active-low, 1 = active-high
                        BitField('pin_config',
                                 0b00010000),  # 0 = push-pull, 1 = open-drain
                        BitField('z_enable', 0b00100000),
                        BitField('y_enable', 0b01000000),
                        BitField('x_enable', 0b10000000),
                    )),
                Register('MAGNETOMETER_INTERRUPT_SOURCE',
                         0x13,
                         fields=(
                             BitField('event', 0b00000001),
                             BitField('overflow', 0b00000010),
                             BitField('z_negative', 0b00000100),
                             BitField('y_negative', 0b00001000),
                             BitField('x_negative', 0b00010000),
                             BitField('z_positive', 0b00100000),
                             BitField('y_positive', 0b01000000),
                             BitField('x_positive', 0b10000000),
                         )),
                Register('MAGNETOMETER_INTERRUPT_THRESHOLD',
                         0x14 | 0x80,
                         fields=(BitField('threshold',
                                          0xFFFF,
                                          adapter=U16ByteSwapAdapter()), ),
                         bit_width=16),
                Register('MAGNETOMETER_OFFSET',
                         0x16 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),
                Register('HP_ACCELEROMETER_REFERENCE',
                         0x1c | 0x80,
                         fields=(
                             BitField('x', 0xFF0000),
                             BitField('y', 0x00FF00),
                             BitField('z', 0x0000FF),
                         ),
                         bit_width=8 * 3),
                Register('CONTROL0',
                         0x1f,
                         fields=(
                             BitField('int2_high_pass', 0b00000001),
                             BitField('int1_high_pass', 0b00000010),
                             BitField('click_high_pass', 0b00000100),
                             BitField('fifo_threshold', 0b00100000),
                             BitField('fifo_enable', 0b01000000),
                             BitField('reboot_memory', 0b10000000),
                         )),
                Register('CONTROL1',
                         0x20,
                         fields=(
                             BitField('accel_x_enable', 0b00000001),
                             BitField('accel_y_enable', 0b00000010),
                             BitField('accel_z_enable', 0b00000100),
                             BitField('block_data_update', 0b00001000),
                             BitField('accel_data_rate_hz',
                                      0b11110000,
                                      adapter=LookupAdapter({
                                          0: 0,
                                          3.125: 0b0001,
                                          6.25: 0b0010,
                                          12.5: 0b0011,
                                          25: 0b0100,
                                          50: 0b0101,
                                          100: 0b0110,
                                          200: 0b0111,
                                          400: 0b1000,
                                          800: 0b1001,
                                          1600: 0b1010
                                      })),
                         )),
                Register('CONTROL2',
                         0x21,
                         fields=(
                             BitField('serial_interface_mode', 0b00000001),
                             BitField('accel_self_test', 0b00000010),
                             BitField('accel_full_scale_g',
                                      0b00111000,
                                      adapter=LookupAdapter({
                                          2: 0b000,
                                          4: 0b001,
                                          6: 0b010,
                                          8: 0b011,
                                          16: 0b100
                                      })),
                             BitField('accel_antialias_bw_hz',
                                      0b11000000,
                                      adapter=LookupAdapter({
                                          50: 0b11,
                                          362: 0b10,
                                          194: 0b01,
                                          773: 0b00
                                      })),
                         )),

                # Known in the datasheet as CTRL3
                Register('INTERRUPT1',
                         0x22,
                         fields=(
                             BitField('enable_fifo_empty', 0b00000001),
                             BitField('enable_accel_dataready', 0b00000010),
                             BitField('enable_accelerometer', 0b00000100),
                             BitField('enable_magnetometer', 0b00001000),
                             BitField('enable_ig2', 0b00010000),
                             BitField('enable_ig1', 0b00100000),
                             BitField('enable_click', 0b01000000),
                             BitField('enable_boot', 0b10000000),
                         )),

                # Known in the datasheet as CTRL4
                Register('INTERRUPT2',
                         0x23,
                         fields=(
                             BitField('enable_fifo', 0b00000001),
                             BitField('enable_fifo_overrun', 0b00000010),
                             BitField('enable_mag_dataready', 0b00000100),
                             BitField('enable_accel_dataready', 0b00001000),
                             BitField('enable_magnetometer', 0b00010000),
                             BitField('enable_ig2', 0b00100000),
                             BitField('enable_ig1', 0b01000000),
                             BitField('enable_click', 0b10000000),
                         )),
                Register('CONTROL5',
                         0x24,
                         fields=(
                             BitField('latch_int1', 0b00000001),
                             BitField('latch_int2', 0b00000010),
                             BitField('mag_data_rate_hz',
                                      0b00011100,
                                      adapter=LookupAdapter({
                                          3.125: 0b000,
                                          6.25: 0b001,
                                          12.5: 0b010,
                                          25: 0b011,
                                          50: 0b100,
                                          100: 0b101,
                                      })),
                             BitField('mag_resolution', 0b01100000),
                             BitField('enable_temperature', 0b10000000),
                         )),
                Register('CONTROL6',
                         0x25,
                         fields=(BitField('mag_full_scale_gauss',
                                          0b01100000,
                                          adapter=LookupAdapter({
                                              2: 0b00,
                                              4: 0b01,
                                              8: 0b10,
                                              12: 0b11
                                          })), )),
                Register(
                    'CONTROL7',
                    0x26,
                    fields=(
                        BitField('mag_mode',
                                 0b00000011,
                                 adapter=LookupAdapter({
                                     'continuous': 0b00,
                                     'single': 0b01,
                                     'off': 0b10
                                 })),
                        BitField('mag_lowpowermode', 0b00000100),
                        BitField('temperature_only', 0b00010000),
                        BitField('filter_accel', 0b00100000),
                        BitField('high_pass_mode_accel',
                                 0b11000000),  # See page 39 of lsm303d.pdf
                    )),

                # Accelerometer interrupt status register
                Register('ACCELEROMETER_STATUS',
                         0x27,
                         fields=(BitField('xdata', 0b00000001),
                                 BitField('ydata', 0b00000010),
                                 BitField('zdata', 0b00000100),
                                 BitField('data', 0b00001000),
                                 BitField('xoverrun', 0b00010000),
                                 BitField('yoverrun', 0b00100000),
                                 BitField('zoverrun', 0b01000000),
                                 BitField('overrun', 0b10000000))),

                # X/Y/Z values from accelerometer
                Register('ACCELEROMETER',
                         0x28 | 0x80,
                         fields=(
                             BitField('x',
                                      0xFFFF00000000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('y',
                                      0x0000FFFF0000,
                                      adapter=S16ByteSwapAdapter()),
                             BitField('z',
                                      0x00000000FFFF,
                                      adapter=S16ByteSwapAdapter()),
                         ),
                         bit_width=8 * 6),

                # FIFO control register
                Register('FIFO_CONTROL',
                         0x2e,
                         fields=(
                             BitField('mode', 0b11100000),
                             BitField('threshold', 0b00011111),
                         )),

                # FIFO status register
                Register(
                    'FIFO_STATUS',
                    0x2f,
                    fields=(
                        BitField('threshold_exceeded', 1 << 7),
                        BitField('overrun', 1 << 6),
                        BitField('empty', 1 << 5),
                        BitField('unread_levels', 0b00011111
                                 ),  # Current number of unread FIFO levels
                    )),

                # 0x30: Internal interrupt generator 1: configuration register
                # 0x31: Internal interrupt generator 1: status register
                # 0x32: Internal interrupt generator 1: threshold register
                # 0x33: Internal interrupt generator 1: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x30
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x31
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x32
                        BitField('threshold', 0xff << 8),
                        # 0x33
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x34: Internal interrupt generator 2: configuration register
                # 0x35: Internal interrupt generator 2: status register
                # 0x36: Internal interrupt generator 2: threshold register
                # 0x37: Internal interrupt generator 2: duration register
                Register(
                    'IG_CONFIG1',
                    0x30 | 0x80,
                    fields=(
                        # 0x34
                        BitField('and_or_combination', 1 << 31),
                        BitField('6d_enable', 1 << 30),
                        BitField('z_high_enable', 1 << 29),
                        BitField('z_low_enable', 1 << 28),
                        BitField('y_high_enable', 1 << 27),
                        BitField('y_low_enable', 1 << 26),
                        BitField('x_high_enable', 1 << 25),
                        BitField('x_low_enble', 1 << 24),
                        # 0x35
                        BitField('interrupt_status', 1 << 23),
                        BitField('z_high', 1 << 22),
                        BitField('z_low', 1 << 21),
                        BitField('y_high', 1 << 20),
                        BitField('y_low', 1 << 19),
                        BitField('x_high', 1 << 18),
                        BitField('x_low', 1 << 17),
                        BitField('status', 1 << 16),
                        # 0x36
                        BitField('threshold', 0xff << 8),
                        # 0x37
                        BitField('duration', 0xff),
                    ),
                    bit_width=32),

                # 0x38: Click: configuration register
                # 0x39: Click: status register
                # 0x3A: Click: threshold register
                # 0x3B: Click: time limit register
                # 0x3C: Click: time latency register
                # 0x3D: Click: time window register
                Register(
                    'CLICK',
                    0x38 | 0x80,
                    fields=(
                        # 0x38
                        # bits 1 << 47 and 1 << 46 are unimplemented
                        BitField('z_doubleclick_enable', 1 << 45),
                        BitField('z_click_enable', 1 << 44),
                        BitField('y_doubleclick_enable', 1 << 43),
                        BitField('y_click_enable', 1 << 42),
                        BitField('x_doubleclick_enable', 1 << 41),
                        BitField('x_click_enable', 1 << 40),
                        # 0x39
                        # bit 1 << 39 is unimplemented
                        BitField('interrupt_enable', 1 << 38),
                        BitField('doubleclick_enable', 1 << 37),
                        BitField('click_enable', 1 << 36),
                        BitField(
                            'sign', 1 <<
                            35),  # 0 positive detection, 1 negative detection
                        BitField('z', 1 << 34),
                        BitField('y', 1 << 33),
                        BitField('x', 1 << 32),
                        # 0x3A
                        BitField('threshod', 0xFF << 24),
                        # 0x3B
                        BitField('time_limit', 0xFF << 16),
                        # 0x3C
                        BitField('time_latency', 0xFF << 8),
                        # 0x3D
                        BitField('time_window', 0xFF),
                    ),
                    bit_width=8 * 6),

                # Controls the threshold and duration of returning to sleep mode
                Register(
                    'ACT',
                    0x3e | 0x80,
                    fields=(
                        BitField('threshold', 0xFF00),  # 1 LSb = 16mg
                        BitField('duration',
                                 0x00FF)  # (duration + 1) * 8/output_data_rate
                    ),
                    bit_width=16)))

        self._is_setup = False

        self._accel_full_scale_g = 2
        self._mag_full_scale_guass = 2
Beispiel #20
0
class BME280:
    def __init__(self, i2c_addr=I2C_ADDRESS_GND, i2c_dev=None):
        self.calibration = BME280Calibration()
        self._is_setup = False
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._bme280 = Device(
            [I2C_ADDRESS_GND, I2C_ADDRESS_VCC],
            i2c_dev=self._i2c_dev,
            bit_width=8,
            registers=(
                Register('CHIP_ID', 0xD0, fields=(BitField('id', 0xFF), )),
                Register('RESET', 0xE0, fields=(BitField('reset', 0xFF), )),
                Register(
                    'STATUS',
                    0xF3,
                    fields=(
                        BitField('measuring',
                                 0b00001000),  # 1 when conversion is running
                        BitField(
                            'im_update',
                            0b00000001),  # 1 when NVM data is being copied
                    )),
                Register(
                    'CTRL_MEAS',
                    0xF4,
                    fields=(
                        BitField(
                            'osrs_t',
                            0b11100000,  # Temperature oversampling
                            adapter=LookupAdapter({
                                1: 0b001,
                                2: 0b010,
                                4: 0b011,
                                8: 0b100,
                                16: 0b101
                            })),
                        BitField(
                            'osrs_p',
                            0b00011100,  # Pressure oversampling
                            adapter=LookupAdapter({
                                1: 0b001,
                                2: 0b010,
                                4: 0b011,
                                8: 0b100,
                                16: 0b101
                            })),
                        BitField(
                            'mode',
                            0b00000011,  # Power mode
                            adapter=LookupAdapter({
                                'sleep': 0b00,
                                'forced': 0b10,
                                'normal': 0b11
                            })),
                    )),
                Register(
                    'CTRL_HUM',
                    0xF2,
                    fields=(
                        BitField(
                            'osrs_h',
                            0b00000111,  # Humidity oversampling
                            adapter=LookupAdapter({
                                1: 0b001,
                                2: 0b010,
                                4: 0b011,
                                8: 0b100,
                                16: 0b101
                            })), )),
                Register(
                    'CONFIG',
                    0xF5,
                    fields=(
                        BitField(
                            't_sb',
                            0b11100000,  # Temp standby duration in normal mode
                            adapter=LookupAdapter({
                                0.5: 0b000,
                                62.5: 0b001,
                                125: 0b010,
                                250: 0b011,
                                500: 0b100,
                                1000: 0b101,
                                10: 0b110,
                                20: 0b111
                            })),
                        BitField(
                            'filter', 0b00011100
                        ),  # Controls the time constant of the IIR filter
                        BitField(
                            'spi3w_en', 0b0000001, read_only=True
                        ),  # Enable 3-wire SPI interface when set to 1. IE: Don't set this bit!
                    )),
                Register('DATA',
                         0xF7,
                         fields=(BitField('humidity', 0x000000000000FFFF),
                                 BitField('temperature', 0x000000FFFFF00000),
                                 BitField('pressure', 0xFFFFF00000000000)),
                         bit_width=8 * 8),
                Register(
                    'CALIBRATION',
                    0x88,
                    fields=(
                        BitField('dig_t1',
                                 0xFFFF << 16 * 12,
                                 adapter=U16Adapter()),  # 0x88 0x89
                        BitField('dig_t2',
                                 0xFFFF << 16 * 11,
                                 adapter=S16Adapter()),  # 0x8A 0x8B
                        BitField('dig_t3',
                                 0xFFFF << 16 * 10,
                                 adapter=S16Adapter()),  # 0x8C 0x8D
                        BitField('dig_p1',
                                 0xFFFF << 16 * 9,
                                 adapter=U16Adapter()),  # 0x8E 0x8F
                        BitField('dig_p2',
                                 0xFFFF << 16 * 8,
                                 adapter=S16Adapter()),  # 0x90 0x91
                        BitField('dig_p3',
                                 0xFFFF << 16 * 7,
                                 adapter=S16Adapter()),  # 0x92 0x93
                        BitField('dig_p4',
                                 0xFFFF << 16 * 6,
                                 adapter=S16Adapter()),  # 0x94 0x95
                        BitField('dig_p5',
                                 0xFFFF << 16 * 5,
                                 adapter=S16Adapter()),  # 0x96 0x97
                        BitField('dig_p6',
                                 0xFFFF << 16 * 4,
                                 adapter=S16Adapter()),  # 0x98 0x99
                        BitField('dig_p7',
                                 0xFFFF << 16 * 3,
                                 adapter=S16Adapter()),  # 0x9A 0x9B
                        BitField('dig_p8',
                                 0xFFFF << 16 * 2,
                                 adapter=S16Adapter()),  # 0x9C 0x9D
                        BitField('dig_p9',
                                 0xFFFF << 16 * 1,
                                 adapter=S16Adapter()),  # 0x9E 0x9F
                        BitField('dig_h1', 0x00FF),  # 0xA1 uint8
                    ),
                    bit_width=26 * 8),
                Register(
                    'CALIBRATION2',
                    0xE1,
                    fields=(
                        BitField('dig_h2',
                                 0xFFFF0000000000,
                                 adapter=S16Adapter()),  # 0xE1 0xE2
                        BitField('dig_h3', 0x0000FF00000000),  # 0xE3 uint8
                        BitField('dig_h4',
                                 0x000000FFFF0000,
                                 adapter=H4Adapter()),  # 0xE4 0xE5[3:0]
                        BitField('dig_h5',
                                 0x00000000FFFF00,
                                 adapter=H5Adapter()),  # 0xE5[7:4] 0xE6
                        BitField('dig_h6',
                                 0x000000000000FF,
                                 adapter=S8Adapter())  # 0xE7 int8
                    ),
                    bit_width=7 * 8)))

    def setup(self,
              mode='normal',
              temperature_oversampling=16,
              pressure_oversampling=16,
              humidity_oversampling=16,
              temperature_standby=500):
        if self._is_setup:
            return
        self._is_setup = True

        self._bme280.select_address(self._i2c_addr)
        self._mode = mode

        if mode == "forced":
            mode = "sleep"

        #try:
        #    chip = self._bme280.get('CHIP_ID')
        #    if chip.id != CHIP_ID:
        #        raise RuntimeError("Unable to find bme280 on 0x{:02x}, CHIP_ID returned {:02x}".format(self._i2c_addr, chip.id))
        #except IOError:
        #    raise RuntimeError("Unable to find bme280 on 0x{:02x}, IOError".format(self._i2c_addr))

        self._bme280.set('RESET', reset=0xB6)
        time.sleep(0.1)

        self._bme280.set('CTRL_HUM', osrs_h=humidity_oversampling)

        self._bme280.set('CTRL_MEAS',
                         mode=mode,
                         osrs_t=temperature_oversampling,
                         osrs_p=pressure_oversampling)

        self._bme280.set('CONFIG', t_sb=temperature_standby, filter=2)

        self.calibration.set_from_namedtuple(self._bme280.get('CALIBRATION'))
        self.calibration.set_from_namedtuple(self._bme280.get('CALIBRATION2'))

    def update_sensor(self):
        self.setup()

        if self._mode == "forced":
            self._bme280.set('CTRL_MEAS', mode="forced")
            while self._bme280.get('STATUS').measuring:
                time.sleep(0.001)

        raw = self._bme280.get('DATA')
        self.temperature = self.calibration.compensate_temperature(
            raw.temperature)
        self.pressure = self.calibration.compensate_pressure(
            raw.pressure) / 100.0
        self.humidity = self.calibration.compensate_humidity(raw.humidity)

    def get_temperature(self):
        self.update_sensor()
        return self.temperature

    def get_pressure(self):
        self.update_sensor()
        return self.pressure

    def get_humidity(self):
        self.update_sensor()
        return self.humidity

    def get_altitude(self, qnh=1017):
        self.update_sensor()
        self.altitude = 44330.0 * (1.0 - pow(self.pressure / qnh,
                                             (1.0 / 5.255)))
        return self.altitude

    def all(self, qnh=1017):
        self.update_sensor()
        self.altitude = 44330.0 * (1.0 - pow(self.pressure / qnh,
                                             (1.0 / 5.255)))
        return self.temperature, self.pressure, self.humidity, self.altitude
Beispiel #21
0
 def __init__(self, i2c_addr=I2C_ADDRESS_GND, i2c_dev=None):
     self.calibration = BME280Calibration()
     self._is_setup = False
     self._i2c_addr = i2c_addr
     self._i2c_dev = i2c_dev
     self._bme280 = Device(
         [I2C_ADDRESS_GND, I2C_ADDRESS_VCC],
         i2c_dev=self._i2c_dev,
         bit_width=8,
         registers=(
             Register('CHIP_ID', 0xD0, fields=(BitField('id', 0xFF), )),
             Register('RESET', 0xE0, fields=(BitField('reset', 0xFF), )),
             Register(
                 'STATUS',
                 0xF3,
                 fields=(
                     BitField('measuring',
                              0b00001000),  # 1 when conversion is running
                     BitField(
                         'im_update',
                         0b00000001),  # 1 when NVM data is being copied
                 )),
             Register(
                 'CTRL_MEAS',
                 0xF4,
                 fields=(
                     BitField(
                         'osrs_t',
                         0b11100000,  # Temperature oversampling
                         adapter=LookupAdapter({
                             1: 0b001,
                             2: 0b010,
                             4: 0b011,
                             8: 0b100,
                             16: 0b101
                         })),
                     BitField(
                         'osrs_p',
                         0b00011100,  # Pressure oversampling
                         adapter=LookupAdapter({
                             1: 0b001,
                             2: 0b010,
                             4: 0b011,
                             8: 0b100,
                             16: 0b101
                         })),
                     BitField(
                         'mode',
                         0b00000011,  # Power mode
                         adapter=LookupAdapter({
                             'sleep': 0b00,
                             'forced': 0b10,
                             'normal': 0b11
                         })),
                 )),
             Register(
                 'CTRL_HUM',
                 0xF2,
                 fields=(
                     BitField(
                         'osrs_h',
                         0b00000111,  # Humidity oversampling
                         adapter=LookupAdapter({
                             1: 0b001,
                             2: 0b010,
                             4: 0b011,
                             8: 0b100,
                             16: 0b101
                         })), )),
             Register(
                 'CONFIG',
                 0xF5,
                 fields=(
                     BitField(
                         't_sb',
                         0b11100000,  # Temp standby duration in normal mode
                         adapter=LookupAdapter({
                             0.5: 0b000,
                             62.5: 0b001,
                             125: 0b010,
                             250: 0b011,
                             500: 0b100,
                             1000: 0b101,
                             10: 0b110,
                             20: 0b111
                         })),
                     BitField(
                         'filter', 0b00011100
                     ),  # Controls the time constant of the IIR filter
                     BitField(
                         'spi3w_en', 0b0000001, read_only=True
                     ),  # Enable 3-wire SPI interface when set to 1. IE: Don't set this bit!
                 )),
             Register('DATA',
                      0xF7,
                      fields=(BitField('humidity', 0x000000000000FFFF),
                              BitField('temperature', 0x000000FFFFF00000),
                              BitField('pressure', 0xFFFFF00000000000)),
                      bit_width=8 * 8),
             Register(
                 'CALIBRATION',
                 0x88,
                 fields=(
                     BitField('dig_t1',
                              0xFFFF << 16 * 12,
                              adapter=U16Adapter()),  # 0x88 0x89
                     BitField('dig_t2',
                              0xFFFF << 16 * 11,
                              adapter=S16Adapter()),  # 0x8A 0x8B
                     BitField('dig_t3',
                              0xFFFF << 16 * 10,
                              adapter=S16Adapter()),  # 0x8C 0x8D
                     BitField('dig_p1',
                              0xFFFF << 16 * 9,
                              adapter=U16Adapter()),  # 0x8E 0x8F
                     BitField('dig_p2',
                              0xFFFF << 16 * 8,
                              adapter=S16Adapter()),  # 0x90 0x91
                     BitField('dig_p3',
                              0xFFFF << 16 * 7,
                              adapter=S16Adapter()),  # 0x92 0x93
                     BitField('dig_p4',
                              0xFFFF << 16 * 6,
                              adapter=S16Adapter()),  # 0x94 0x95
                     BitField('dig_p5',
                              0xFFFF << 16 * 5,
                              adapter=S16Adapter()),  # 0x96 0x97
                     BitField('dig_p6',
                              0xFFFF << 16 * 4,
                              adapter=S16Adapter()),  # 0x98 0x99
                     BitField('dig_p7',
                              0xFFFF << 16 * 3,
                              adapter=S16Adapter()),  # 0x9A 0x9B
                     BitField('dig_p8',
                              0xFFFF << 16 * 2,
                              adapter=S16Adapter()),  # 0x9C 0x9D
                     BitField('dig_p9',
                              0xFFFF << 16 * 1,
                              adapter=S16Adapter()),  # 0x9E 0x9F
                     BitField('dig_h1', 0x00FF),  # 0xA1 uint8
                 ),
                 bit_width=26 * 8),
             Register(
                 'CALIBRATION2',
                 0xE1,
                 fields=(
                     BitField('dig_h2',
                              0xFFFF0000000000,
                              adapter=S16Adapter()),  # 0xE1 0xE2
                     BitField('dig_h3', 0x0000FF00000000),  # 0xE3 uint8
                     BitField('dig_h4',
                              0x000000FFFF0000,
                              adapter=H4Adapter()),  # 0xE4 0xE5[3:0]
                     BitField('dig_h5',
                              0x00000000FFFF00,
                              adapter=H5Adapter()),  # 0xE5[7:4] 0xE6
                     BitField('dig_h6',
                              0x000000000000FF,
                              adapter=S8Adapter())  # 0xE7 int8
                 ),
                 bit_width=7 * 8)))
Beispiel #22
0
    def __init__(self, i2c_dev=None):
        self._as7262 = Device(
            0x49,
            i2c_dev=as7262VirtualRegisterBus(i2c_dev=i2c_dev),
            bit_width=8,
            registers=(
                Register('VERSION',
                         0x00,
                         fields=(
                             BitField('hw_type', 0xFF000000),
                             BitField('hw_version', 0x00FF0000),
                             BitField('fw_version',
                                      0x0000FFFF,
                                      adapter=FWVersionAdapter()),
                         ),
                         bit_width=32,
                         read_only=True),
                Register('CONTROL',
                         0x04,
                         fields=(
                             BitField('reset', 0b10000000),
                             BitField('interrupt', 0b01000000),
                             BitField('gain_x',
                                      0b00110000,
                                      adapter=LookupAdapter({
                                          1: 0b00,
                                          3.7: 0b01,
                                          16: 0b10,
                                          64: 0b11
                                      })),
                             BitField('measurement_mode', 0b00001100),
                             BitField('data_ready', 0b00000010),
                         )),
                Register('INTEGRATION_TIME',
                         0x05,
                         fields=(BitField(
                             'ms', 0xFF, adapter=IntegrationTimeAdapter()), )),
                Register('TEMPERATURE',
                         0x06,
                         fields=(BitField('degrees_c', 0xFF), )),
                Register('LED_CONTROL',
                         0x07,
                         fields=(
                             BitField('illumination_current_limit_ma',
                                      0b00110000,
                                      adapter=LookupAdapter({
                                          12.5: 0b00,
                                          25: 0b01,
                                          50: 0b10,
                                          100: 0b11
                                      })),
                             BitField('illumination_enable', 0b00001000),
                             BitField('indicator_current_limit_ma',
                                      0b00000110,
                                      adapter=LookupAdapter({
                                          1: 0b00,
                                          2: 0b01,
                                          4: 0b10,
                                          8: 0b11
                                      })),
                             BitField('indicator_enable', 0b00000001),
                         )),
                Register('DATA',
                         0x08,
                         fields=(
                             BitField('v', 0xFFFF00000000000000000000),
                             BitField('b', 0x0000FFFF0000000000000000),
                             BitField('g', 0x00000000FFFF000000000000),
                             BitField('y', 0x000000000000FFFF00000000),
                             BitField('o', 0x0000000000000000FFFF0000),
                             BitField('r', 0x00000000000000000000FFFF),
                         ),
                         bit_width=96),
                Register('CALIBRATED_DATA',
                         0x14,
                         fields=(
                             BitField('v',
                                      0xFFFFFFFF << (32 * 5),
                                      adapter=FloatAdapter()),
                             BitField('b',
                                      0xFFFFFFFF << (32 * 4),
                                      adapter=FloatAdapter()),
                             BitField('g',
                                      0xFFFFFFFF << (32 * 3),
                                      adapter=FloatAdapter()),
                             BitField('y',
                                      0xFFFFFFFF << (32 * 2),
                                      adapter=FloatAdapter()),
                             BitField('o',
                                      0xFFFFFFFF << (32 * 1),
                                      adapter=FloatAdapter()),
                             BitField('r',
                                      0xFFFFFFFF << (32 * 0),
                                      adapter=FloatAdapter()),
                         ),
                         bit_width=192),
            ))

        # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
        # Iterate through all register fields and export their lookup tables to constants
        for register in self._as7262.registers:
            register = self._as7262.registers[register]
            for field in register.fields:
                field = register.fields[field]
                if isinstance(field.adapter, LookupAdapter):
                    for key in field.adapter.lookup_table:
                        value = field.adapter.lookup_table[key]
                        name = 'AS7262_{register}_{field}_{key}'.format(
                            register=register.name, field=field.name,
                            key=key).upper()
                        locals()[name] = key

        self.soft_reset()
Beispiel #23
0
{% set _dummy = template.registersToFields.update({ rkey: [] }) %}
{{- template.registersToFields[rkey].append(field) or "" -}}
{% endif %}
{% endfor %}
{% endif %}
{% macro values_map(field) %}
{% if field.type == 'enum' %}
{
{% for ekey, enum in field.enum|dictsort %}
        {{ekey}}: {{enum.value}}{{',' if not loop.last }}
{% endfor %}
    }{% endif %}
{%- endmacro %}
{% for key,register in registers|dictsort %}
{% if key in template.registersToFields %}
{{key.upper()}} = Register('{{key.upper()}}', {{register.address}}, fields=(
    {% for field in template.registersToFields[key] %}
    BitField('{{field.key}}', {{utils.mask(field.bitStart, field.bitEnd)}}, bitwidth={{field.bitStart - field.bitEnd + 1}}{% if i2c.endian == 'little' %}, values_in=_byte_swap, values_out=_byte_swap{% endif %}{% if field.type == 'enum' %}, values_map={{values_map(field)}}{% endif %}){{',' if not loop.last }}
    {% endfor %}
), read_only={{register.readWrite == 'R'}}, bitwidth={{register.length}})
{% else %}
{{key.upper()}} = Register('{{key.upper()}}', {{register.address}}, read_only={{register.readWrite == 'R'}}, bitwidth={{register.length}})
{% endif %}
{% endfor %}

{{info.title.lower()}} = Device(I2C_ADDR, registers=(
    {% for key,register in registers|dictsort %}
    {{key.upper()}}{{',' if not loop.last}}
    {% endfor %}
))
Beispiel #24
0
class AS7262:
    def __init__(self, i2c_dev=None):
        self._as7262 = Device(
            0x49,
            i2c_dev=as7262VirtualRegisterBus(i2c_dev=i2c_dev),
            bit_width=8,
            registers=(
                Register('VERSION',
                         0x00,
                         fields=(
                             BitField('hw_type', 0xFF000000),
                             BitField('hw_version', 0x00FF0000),
                             BitField('fw_version',
                                      0x0000FFFF,
                                      adapter=FWVersionAdapter()),
                         ),
                         bit_width=32,
                         read_only=True),
                Register('CONTROL',
                         0x04,
                         fields=(
                             BitField('reset', 0b10000000),
                             BitField('interrupt', 0b01000000),
                             BitField('gain_x',
                                      0b00110000,
                                      adapter=LookupAdapter({
                                          1: 0b00,
                                          3.7: 0b01,
                                          16: 0b10,
                                          64: 0b11
                                      })),
                             BitField('measurement_mode', 0b00001100),
                             BitField('data_ready', 0b00000010),
                         )),
                Register('INTEGRATION_TIME',
                         0x05,
                         fields=(BitField(
                             'ms', 0xFF, adapter=IntegrationTimeAdapter()), )),
                Register('TEMPERATURE',
                         0x06,
                         fields=(BitField('degrees_c', 0xFF), )),
                Register('LED_CONTROL',
                         0x07,
                         fields=(
                             BitField('illumination_current_limit_ma',
                                      0b00110000,
                                      adapter=LookupAdapter({
                                          12.5: 0b00,
                                          25: 0b01,
                                          50: 0b10,
                                          100: 0b11
                                      })),
                             BitField('illumination_enable', 0b00001000),
                             BitField('indicator_current_limit_ma',
                                      0b00000110,
                                      adapter=LookupAdapter({
                                          1: 0b00,
                                          2: 0b01,
                                          4: 0b10,
                                          8: 0b11
                                      })),
                             BitField('indicator_enable', 0b00000001),
                         )),
                Register('DATA',
                         0x08,
                         fields=(
                             BitField('v', 0xFFFF00000000000000000000),
                             BitField('b', 0x0000FFFF0000000000000000),
                             BitField('g', 0x00000000FFFF000000000000),
                             BitField('y', 0x000000000000FFFF00000000),
                             BitField('o', 0x0000000000000000FFFF0000),
                             BitField('r', 0x00000000000000000000FFFF),
                         ),
                         bit_width=96),
                Register('CALIBRATED_DATA',
                         0x14,
                         fields=(
                             BitField('v',
                                      0xFFFFFFFF << (32 * 5),
                                      adapter=FloatAdapter()),
                             BitField('b',
                                      0xFFFFFFFF << (32 * 4),
                                      adapter=FloatAdapter()),
                             BitField('g',
                                      0xFFFFFFFF << (32 * 3),
                                      adapter=FloatAdapter()),
                             BitField('y',
                                      0xFFFFFFFF << (32 * 2),
                                      adapter=FloatAdapter()),
                             BitField('o',
                                      0xFFFFFFFF << (32 * 1),
                                      adapter=FloatAdapter()),
                             BitField('r',
                                      0xFFFFFFFF << (32 * 0),
                                      adapter=FloatAdapter()),
                         ),
                         bit_width=192),
            ))

        # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
        # Iterate through all register fields and export their lookup tables to constants
        for register in self._as7262.registers:
            register = self._as7262.registers[register]
            for field in register.fields:
                field = register.fields[field]
                if isinstance(field.adapter, LookupAdapter):
                    for key in field.adapter.lookup_table:
                        value = field.adapter.lookup_table[key]
                        name = 'AS7262_{register}_{field}_{key}'.format(
                            register=register.name, field=field.name,
                            key=key).upper()
                        locals()[name] = key

        self.soft_reset()

    def soft_reset(self):
        """Set the soft reset register bit of the AS7262."""
        self._as7262.set('CONTROL', reset=1)
        # Polling for the state of the reset flag does not work here
        # since the fragile virtual register state machine cannot
        # respond while in a soft reset condition
        # So, just wait long enough for it to reset fully...
        time.sleep(2.0)

    def get_calibrated_values(self, timeout=10):
        """Return an instance of CalibratedValues containing the 6 spectral bands."""
        t_start = time.time()
        while self._as7262.get('CONTROL').data_ready == 0 and (
                time.time() - t_start) <= timeout:
            pass
        data = self._as7262.get('CALIBRATED_DATA')
        return CalibratedValues(data.r, data.o, data.y, data.g, data.b, data.v)

    def set_gain(self, gain):
        """Set the gain amount of the AS7262.

        :param gain: gain multiplier, one of 1, 3.7, 16 or 64

        """
        self._as7262.set('CONTROL', gain_x=gain)

    def set_measurement_mode(self, mode):
        """Set the AS7262 measurement mode.

        :param mode: 0-3

        """
        self._as7262.set('CONTROL', measurement_mode=mode)

    def set_integration_time(self, time_ms):
        """Set the AS7262 sensor integration time in milliseconds.

        :param time_ms: Time in milliseconds from 0 to ~91

        """
        self._as7262.set('INTEGRATION_TIME', ms=time_ms)

    def set_illumination_led_current(self, current):
        """Set the AS7262 illumination LED current in milliamps.

        :param current: Value in milliamps, one of 12.5, 25, 50 or 100

        """
        self._as7262.set('LED_CONTROL', illumination_current_limit_ma=current)

    def set_indicator_led_current(self, current):
        """Set the AS7262 indicator LED current in milliamps.

        :param current: Value in milliamps, one of 1, 2, 4 or 8

        """
        self._as7262.set('LED_CONTROL', indicator_current_limit_ma=current)

    def set_illumination_led(self, state):
        """Set the AS7262 illumination LED state.

        :param state: True = On, False = Off

        """
        self._as7262.set('LED_CONTROL', illumination_enable=state)

    def set_indicator_led(self, state):
        """Set the AS7262 indicator LED state.

        :param state: True = On, False = Off

        """
        self._as7262.set('LED_CONTROL', indicator_enable=state)

    def get_version(self):
        """Get the hardware type, version and firmware version from the AS7262."""
        version = self._as7262.get('VERSION')
        return version.hw_type, version.hw_version, version.fw_version
Beispiel #25
0
I2C_ADDR_29 = 29
I2C_ADDR_30 = 30
I2C_ADDR_31 = 31
I2C_ADDR = [
    I2C_ADDR_24, I2C_ADDR_25, I2C_ADDR_26, I2C_ADDR_27, I2C_ADDR_28,
    I2C_ADDR_29, I2C_ADDR_30, I2C_ADDR_31
]

CONFIGURATION = Register('CONFIGURATION',
                         1,
                         fields=(BitField('limitHysteresis',
                                          0b0000011000000000,
                                          bitwidth=2,
                                          values_map={
                                              Temp_0C: 0,
                                              Temp_1C5: 1,
                                              Temp_3C: 2,
                                              Temp_6C: 3
                                          }),
                                 BitField('shutdownMode',
                                          0b0000000100000000,
                                          bitwidth=1,
                                          values_map={
                                              continousConversion: 0,
                                              shutdown: 1
                                          })),
                         read_only=False,
                         bitwidth=16)

mcp9808 = Device(I2C_ADDR, registers=(CONFIGURATION))
Beispiel #26
0
device = Device(0x00,
                bus,
                registers=(Register('status',
                                    0x00,
                                    fields=(BitField('interrupt',
                                                     0b00000001,
                                                     read_only=True),
                                            BitField('data_ready', 0b00000010),
                                            BitField('power', 0b10000000),
                                            BitField('monkey',
                                                     0b01111100,
                                                     adapter=x2Adapter()))),
                           Register('measurement_rate',
                                    0x85,
                                    fields=(BitField('integration_time_ms',
                                                     0b00111000,
                                                     adapter=LookupAdapter({
                                                         100:
                                                         0b000,
                                                         50:
                                                         0b001,
                                                         200:
                                                         0b010,
                                                         400:
                                                         0b011,
                                                         150:
                                                         0b100,
                                                         250:
                                                         0b101,
                                                         300:
                                                         0b110,
                                                         350:
                                                         0b111
                                                     })),
                                            BitField('repeat_rate_ms',
                                                     0b00000111,
                                                     adapter=LookupAdapter({
                                                         50:
                                                         0b000,
                                                         100:
                                                         0b001,
                                                         200:
                                                         0b010,
                                                         500:
                                                         0b011,
                                                         1000:
                                                         0b100,
                                                         2000:
                                                         0b101
                                                     }))))))
Beispiel #27
0
MAGNETOMETERX_HIGH = Register('MAGNETOMETERX_HIGH',
                              137,
                              read_only=True,
                              bitwidth=8)
MAGNETOMETERX_LOW = Register('MAGNETOMETERX_LOW',
                             136,
                             read_only=True,
                             bitwidth=8)
MAGNETOMETERY_HIGH = Register('MAGNETOMETERY_HIGH',
                              139,
                              read_only=True,
                              bitwidth=8)
MAGNETOMETERY_LOW = Register('MAGNETOMETERY_LOW',
                             138,
                             read_only=True,
                             bitwidth=8)
MAGNETOMETERZ_HIGH = Register('MAGNETOMETERZ_HIGH',
                              141,
                              read_only=True,
                              bitwidth=8)
MAGNETOMETERZ_LOW = Register('MAGNETOMETERZ_LOW',
                             140,
                             read_only=True,
                             bitwidth=8)

lsm303d = Device(
    I2C_ADDR,
    registers=(ACCELEROMETERX_HIGH, ACCELEROMETERX_LOW, ACCELEROMETERY_HIGH,
               ACCELEROMETERY_LOW, ACCELEROMETERZ_HIGH, ACCELEROMETERZ_LOW,
               MAGNETOMETERX_HIGH, MAGNETOMETERX_LOW, MAGNETOMETERY_HIGH,
               MAGNETOMETERY_LOW, MAGNETOMETERZ_HIGH, MAGNETOMETERZ_LOW))
Beispiel #28
0
    def __init__(self, i2c_addr=0x38, i2c_dev=None):
        """Initialise sensor.

        :param i2c_addr: i2c address of sensor
        :param i2c_dev: SMBus-compatible instance

        """
        self._i2c_addr = i2c_addr
        self._i2c_dev = i2c_dev
        self._is_setup = False
        # Device definition
        self._bh1745 = Device(I2C_ADDRESSES, i2c_dev=self._i2c_dev, bit_width=8, registers=(
            # Part ID should be 0b001011 or 0x0B
            Register('SYSTEM_CONTROL', 0x40, fields=(
                BitField('sw_reset', 0b10000000),
                BitField('int_reset', 0b01000000),
                BitField('part_id', 0b00111111, read_only=True)
            )),

            Register('MODE_CONTROL1', 0x41, fields=(
                BitField('measurement_time_ms', 0b00000111, adapter=LookupAdapter({
                    160: 0b000,
                    320: 0b001,
                    640: 0b010,
                    1280: 0b011,
                    2560: 0b100,
                    5120: 0b101
                })),
            )),

            Register('MODE_CONTROL2', 0x42, fields=(
                BitField('valid', 0b10000000, read_only=True),
                BitField('rgbc_en', 0b00010000),
                BitField('adc_gain_x', 0b00000011, adapter=LookupAdapter({
                    1: 0b00, 2: 0b01, 16: 0b10}))
            )),

            Register('MODE_CONTROL3', 0x44, fields=(
                BitField('on', 0b11111111, adapter=LookupAdapter({True: 2, False: 0})),
            )),

            Register('COLOUR_DATA', 0x50, fields=(
                BitField('red', 0xFFFF000000000000, adapter=U16ByteSwapAdapter()),
                BitField('green', 0x0000FFFF00000000, adapter=U16ByteSwapAdapter()),
                BitField('blue', 0x00000000FFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('clear', 0x000000000000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=64, read_only=True),

            Register('DINT_DATA', 0x58, fields=(
                BitField('data', 0xFFFF, adapter=U16ByteSwapAdapter()),
            ), bit_width=16),

            Register('INTERRUPT', 0x60, fields=(
                BitField('status', 0b10000000, read_only=True),
                BitField('latch', 0b00010000, adapter=LookupAdapter({0: 1, 1: 0})),
                BitField('source', 0b00001100, read_only=True, adapter=LookupAdapter({
                    'red': 0b00,
                    'green': 0b01,
                    'blue': 0b10,
                    'clear': 0b11
                })),
                BitField('enable', 0b00000001)
            )),

            # 00: Interrupt status is toggled at each measurement end
            # 01: Interrupt status is updated at each measurement end
            # 10: Interrupt status is updated if 4 consecutive threshold judgements are the same
            # 11: Blah blah ditto above except for 8 consecutive judgements
            Register('PERSISTENCE', 0x61, fields=(
                BitField('mode', 0b00000011, adapter=LookupAdapter({
                    'toggle': 0b00,
                    'update': 0b01,
                    'update_on_4': 0b10,
                    'update_on_8': 0b11
                })),
            )),

            # High threshold defaults to 0xFFFF
            # Low threshold defaults to 0x0000
            Register('THRESHOLD', 0x62, fields=(
                BitField('high', 0xFFFF0000, adapter=U16ByteSwapAdapter()),
                BitField('low', 0x0000FFFF, adapter=U16ByteSwapAdapter())
            ), bit_width=32),

            # Default MANUFACTURER ID is 0xE0h
            Register('MANUFACTURER', 0x92, fields=(
                BitField('id', 0xFF),
            ), read_only=True, volatile=False)
        ))

        self._bh1745.select_address(self._i2c_addr)

        # TODO : Integrate into i2cdevice so that LookupAdapter fields can always be exported to constants
        # Iterate through all register fields and export their lookup tables to constants
        for register in self._bh1745.registers:
            register = self._bh1745.registers[register]
            for field in register.fields:
                field = register.fields[field]
                if isinstance(field.adapter, LookupAdapter):
                    for key in field.adapter.lookup_table:
                        name = 'BH1745_{register}_{field}_{key}'.format(
                            register=register.name,
                            field=field.name,
                            key=key
                        ).upper()
                        globals()[name] = key

        """
        Approximate compensation for the spectral response performance curves
        """
        self._channel_compensation = (2.2, 1.0, 1.8, 10.0)
        self._enable_channel_compensation = True
Beispiel #29
0
ltr559 = Device(
    I2C_ADDR,
    i2c_dev=MockSMBus(0, default_registers={0x86: 0x92}),
    bit_width=8,
    registers=(
        Register('ALS_CONTROL',
                 0x80,
                 fields=(BitField('gain',
                                  0b00011100,
                                  adapter=LookupAdapter({
                                      1: 0b000,
                                      2: 0b001,
                                      4: 0b011,
                                      8: 0b011,
                                      48: 0b110,
                                      96: 0b111
                                  })), BitField('sw_reset', 0b00000010),
                         BitField('mode', 0b00000001))),
        Register('PS_CONTROL',
                 0x81,
                 fields=(BitField('saturation_indicator_enable', 0b00100000),
                         BitField('active',
                                  0b00000011,
                                  adapter=LookupAdapter({
                                      False: 0b00,
                                      True: 0b11
                                  })))),
        Register('PS_LED',
                 0x82,
                 fields=(BitField('pulse_freq_khz',
                                  0b11100000,
                                  adapter=LookupAdapter({
                                      30: 0b000,
                                      40: 0b001,
                                      50: 0b010,
                                      60: 0b011,
                                      70: 0b100,
                                      80: 0b101,
                                      90: 0b110,
                                      100: 0b111
                                  })),
                         BitField('duty_cycle',
                                  0b00011000,
                                  adapter=LookupAdapter({
                                      0.25: 0b00,
                                      0.5: 0b01,
                                      0.75: 0b10,
                                      1.0: 0b11
                                  })),
                         BitField('current_ma',
                                  0b00000111,
                                  adapter=LookupAdapter({
                                      5: 0b000,
                                      10: 0b001,
                                      20: 0b010,
                                      50: 0b011,
                                      100: 0b100
                                  })))),
        Register('PS_N_PULSES', 0x83, fields=(BitField('count',
                                                       0b00001111), )),
        Register('PS_MEAS_RATE',
                 0x84,
                 fields=(BitField('rate_ms',
                                  0b00001111,
                                  adapter=LookupAdapter({
                                      10: 0b1000,
                                      50: 0b0000,
                                      70: 0b0001,
                                      100: 0b0010,
                                      200: 0b0011,
                                      500: 0b0100,
                                      1000: 0b0101,
                                      2000: 0b0110
                                  })), )),
        Register('ALS_MEAS_RATE',
                 0x85,
                 fields=(BitField('integration_time_ms',
                                  0b00111000,
                                  adapter=LookupAdapter({
                                      100: 0b000,
                                      50: 0b001,
                                      200: 0b010,
                                      400: 0b011,
                                      150: 0b100,
                                      250: 0b101,
                                      300: 0b110,
                                      350: 0b111
                                  })),
                         BitField('repeat_rate_ms',
                                  0b00000111,
                                  adapter=LookupAdapter({
                                      50: 0b000,
                                      100: 0b001,
                                      200: 0b010,
                                      500: 0b011,
                                      1000: 0b100,
                                      2000: 0b101
                                  })))),
        Register(
            'PART_ID',
            0x86,
            fields=(
                BitField('part_number', 0b11110000),  # Should be 0x09H
                BitField('revision', 0b00001111)  # Should be 0x02H
            ),
            read_only=True,
            volatile=False),
        Register(
            'MANUFACTURER_ID',
            0x87,
            fields=(
                BitField('manufacturer_id', 0b11111111),  # Should be 0x05H
            ),
            read_only=True),

        # This will address 0x88, 0x89, 0x8A and 0x8B as a continuous 32bit register
        Register('ALS_DATA',
                 0x88,
                 fields=(BitField('ch1',
                                  0xFFFF0000,
                                  bit_width=16,
                                  adapter=U16ByteSwapAdapter()),
                         BitField('ch0',
                                  0x0000FFFF,
                                  bit_width=16,
                                  adapter=U16ByteSwapAdapter())),
                 read_only=True,
                 bit_width=32),
        Register(
            'ALS_PS_STATUS',
            0x8C,
            fields=(
                BitField('als_data_valid', 0b10000000),
                BitField('als_gain',
                         0b01110000,
                         adapter=LookupAdapter({
                             1: 0b000,
                             2: 0b001,
                             4: 0b010,
                             8: 0b011,
                             48: 0b110,
                             96: 0b111
                         })),
                BitField('als_interrupt',
                         0b00001000),  # True = Interrupt is active
                BitField('als_data', 0b00000100),  # True = New data available
                BitField('ps_interrupt',
                         0b00000010),  # True = Interrupt is active
                BitField('ps_data', 0b00000001)  # True = New data available
            ),
            read_only=True),

        # The PS data is actually an 11bit value but since B3 is reserved it'll (probably) read as 0
        # We could mask the result if necessary
        Register('PS_DATA',
                 0x8D,
                 fields=(BitField('ch0', 0xFF0F, adapter=Bit12Adapter()),
                         BitField('saturation', 0x0080)),
                 bit_width=16,
                 read_only=True),

        # INTERRUPT allows the interrupt pin and function behaviour to be configured.
        Register('INTERRUPT',
                 0x8F,
                 fields=(BitField('polarity', 0b00000100),
                         BitField('mode',
                                  0b00000011,
                                  adapter=LookupAdapter({
                                      'off': 0b00,
                                      'ps': 0b01,
                                      'als': 0b10,
                                      'als+ps': 0b11
                                  })))),
        Register('PS_THRESHOLD',
                 0x90,
                 fields=(BitField('upper',
                                  0xFF0F0000,
                                  adapter=Bit12Adapter(),
                                  bit_width=16),
                         BitField('lower',
                                  0x0000FF0F,
                                  adapter=Bit12Adapter(),
                                  bit_width=16)),
                 bit_width=32),

        # PS_OFFSET defines the measurement offset value to correct for proximity
        # offsets caused by device variations, crosstalk and other environmental factors.
        Register(
            'PS_OFFSET',
            0x94,
            fields=(
                BitField('offset',
                         0x03FF),  # Last two bits of 0x94, full 8 bits of 0x95
            ),
            bit_width=16),

        # Defines the upper and lower limits of the ALS reading.
        # An interrupt is triggered if values fall outside of this range.
        # See also INTERRUPT_PERSIST.
        Register('ALS_THRESHOLD',
                 0x97,
                 fields=(BitField('upper',
                                  0xFFFF0000,
                                  adapter=U16ByteSwapAdapter(),
                                  bit_width=16),
                         BitField('lower',
                                  0x0000FFFF,
                                  adapter=U16ByteSwapAdapter(),
                                  bit_width=16)),
                 bit_width=32),

        # This register controls how many values must fall outside of the range defined
        # by upper and lower threshold limits before the interrupt is asserted.

        # In the case of both PS and ALS, a 0 value indicates that every value outside
        # the threshold range should be counted.
        # Values therein map to n+1 , ie: 0b0001 requires two consecutive values.
        Register('INTERRUPT_PERSIST',
                 0x9E,
                 fields=(BitField('PS', 0xF0), BitField('ALS', 0x0F)))))
Beispiel #30
0
        CHANNEL_3: 2,
        CHANNEL_4: 3
    })
    BitField('DeviceOperatingMode', 0b0000000010000000, bitwidth=1, values_in=_byte_swap, values_out=_byte_swap, values_map={
        CONTINUOUS_CONVERSION: 0,
        SINGLE_SHOT: 1
    })
    BitField('ProgrammableGain', 0b0000011100000000, bitwidth=3, values_in=_byte_swap, values_out=_byte_swap, values_map={
        PGA0_256: 5,
        PGA0_512: 4,
        PGA1_024V: 3,
        PGA2_048V: 2,
        PGA4_096V: 1,
        PGA6_144V: 0
    })
    BitField('SampleRate', 0b0000000001110000, bitwidth=3, values_in=_byte_swap, values_out=_byte_swap, values_map={
        HZ128: 0,
        HZ1600: 4,
        HZ2400: 5,
        HZ250: 1,
        HZ3300: 6,
        HZ490: 2,
        HZ920: 3
    })
), read_only=False, bitwidth=16)
CONVERSION = Register('CONVERSION', 0, read_only=True, bitwidth=16)

ads1015 = Device(I2C_ADDR, registers=(
    CONFIG,
    CONVERSION
))