Пример #1
0
    def test_read(self):
        res = []
        res2 = []
        res3 = []

        bus = SMBus(1)

        # Read bytes
        for k in range(2):
            x = bus.read_byte_data(80, k)
            res.append(x)
        self.assertEqual(len(res), 2, msg="Result array of incorrect length.")

        # Read word
        x = bus.read_word_data(80, 0)
        res2.append(x & 255)
        res2.append(x / 256)
        self.assertEqual(len(res2), 2, msg="Result array of incorrect length.")
        self.assertListEqual(res, res2, msg="Byte and word reads differ")

        # Read block of N bytes
        n = 2
        x = bus.read_i2c_block_data(80, 0, n)
        res3.extend(x)
        self.assertEqual(len(res3), n, msg="Result array of incorrect length.")
        self.assertListEqual(res, res3, msg="Byte and block reads differ")

        bus.close()
Пример #2
0
    class I2cBus(BaseI2cDriver.I2cBus):

        def __init__(self, bus_id):
            super().__init__(bus_id)
            try:
                self.bus = SMBus(bus_id)
            except Exception as e:
                raise InvalidDriverError(
                    'Unable to initialize i2c connection with bus {}. Check if i2c bus is avalable.'.format(bus_id), e)

        def close(self):
            if self.bus is not None:
                self.bus.close()

        def read_byte(self, addr: int, register: int) -> int:
            return self.bus.read_byte_data(addr, register)

        def read_word(self, addr: int, register: int) -> int:
            return self.bus.read_word_data(addr, register)

        def read_block(self, addr: int, register, length: int) -> List[int]:
            return self.bus.read_i2c_block_data(addr, register, length)

        def write_byte_data(self, addr, register, value):
            self.bus.write_byte_data(addr, register, value)

        def write_word_data(self, addr, register, value):
            self.bus.write_word_data(addr, register, value)

        def write_block_data(self, addr, register, data):
            self.bus.write_i2c_block_data(addr, register, data)
Пример #3
0
class InputModule(AbstractInput):
    """ 
    A sensor support class that measure the MLX90614's ambient and object temperature.
    """
    def __init__(self, input_dev, testing=False):
        super(InputModule, self).__init__(input_dev, testing=testing, name=__name__)

        self.MLX90614_RAWIR1=0x04
        self.MLX90614_RAWIR2=0x05
        self.MLX90614_TA=0x06
        self.MLX90614_TOBJ1=0x07
        self.MLX90614_TOBJ2=0x08
        
        self.MLX90614_TOMAX=0x20
        self.MLX90614_TOMIN=0x21
        self.MLX90614_PWMCTRL=0x22
        self.MLX90614_TARANGE=0x23
        self.MLX90614_EMISS=0x24
        self.MLX90614_CONFIG=0x25
        self.MLX90614_ADDR=0x0E
        self.MLX90614_ID1=0x3C
        self.MLX90614_ID2=0x3D
        self.MLX90614_ID3=0x3E
        self.MLX90614_ID4=0x3F

        if not testing:
            self.initialize_input()

    def initialize_input(self):
        from smbus2 import SMBus

        self.i2c_address = int(str(self.input_dev.i2c_location), 16)
        self.bus = SMBus(self.input_dev.i2c_bus)

    def read_reg(self, reg_addr):
        return self.bus.read_word_data(self.i2c_address, reg_addr)
 
    def data_to_temp(self, data):
        temp = (data*0.02) - 273.15
        return temp
 
    def get_amb_temp(self):
        data = self.read_reg(self.MLX90614_TA)
        return self.data_to_temp(data)
 
    def get_obj_temp(self):
        data = self.read_reg(self.MLX90614_TOBJ1)
        return self.data_to_temp(data)

    def get_measurement(self):
        """ Gets the ambient (ch0) and object (ch1) temperatures """
        self.return_dict = copy.deepcopy(measurements_dict)

        if self.is_enabled(0):
            self.value_set(0, self.get_amb_temp())

        if self.is_enabled(1):
            self.value_set(1, self.get_obj_temp())

        return self.return_dict
Пример #4
0
    def test_read(self):
        res = []
        res2 = []
        res3 = []

        bus = SMBus(1)

        # Read bytes
        for k in range(2):
            x = bus.read_byte_data(80, k)
            res.append(x)
        self.assertEqual(len(res), 2, msg="Result array of incorrect length.")

        # Read word
        x = bus.read_word_data(80, 0)
        res2.append(x & 255)
        res2.append(x / 256)
        self.assertEqual(len(res2), 2, msg="Result array of incorrect length.")
        self.assertListEqual(res, res2, msg="Byte and word reads differ")

        # Read block of N bytes
        n = 2
        x = bus.read_i2c_block_data(80, 0, n)
        res3.extend(x)
        self.assertEqual(len(res3), n, msg="Result array of incorrect length.")
        self.assertListEqual(res, res3, msg="Byte and block reads differ")

        bus.close()
Пример #5
0
def lm75a(address):

    if 1 < len(sys.argv):
        address = int(sys.argv[1], 16)

    try:
        bus = SMBus(1)
        raw = bus.read_word_data(address, 0) & 0xffff
        raw = ((raw << 8) & 0xffff) + (raw >> 8)
        temperature = (raw / 32.0) / 8.0

        return temperature

    except Exception as e:
        print(e)

    finally:
        bus.close()
Пример #6
0
from smbus2 import SMBus

## address of the device from i2cdetect
sensorAddr = 0x48

## initialize smbus object using bus number
i2c = SMBus(1)

#i2c.write_byte_data(sensorAddr, 1, 0xD)

robot = Robot()

robot.forward()

num = 50
temp = 0
while (temp < num):
    tempWord = i2c.read_word_data(sensorAddr, 0)

    byte1 = tempWord & 0xFF
    byte2 = (tempWord & 0xFF00) >> 12

    temperature = ((byte1 << 4) + byte2) * 0.0625

    print("Temperature: " + str(temperature))
    temp = temp + 1
    time.sleep(0.5)

robot.stop()
GPIO.cleanup()
Пример #7
0
bus.write_byte_data(ADDRESS, 4, 0x44)
b = bus.read_byte_data(ADDRESS, 1)
assert b == 0x44
print("Write byte data@4 OK")

bus.write_byte_data(ADDRESS, 5, 0x55)
b = bus.read_byte_data(ADDRESS, 2)
assert b == 0x55
print("Write byte data@5 OK")

bus.write_byte_data(ADDRESS, 6, 0x66)
b = bus.read_byte_data(ADDRESS, 3)
assert b == 0x66
print("Write byte data@6 OK")

bus.write_word_data(ADDRESS, 9, 0xabcd)
w = bus.read_word_data(ADDRESS, 7)
assert w == 0xabcd
print("Write word data@9, read word data@7 OK")

bus.write_word_data(ADDRESS, 10, 0xef12)
w = bus.read_word_data(ADDRESS, 8)
assert w == 0xef12
print("Write word data@10, read word data@8 OK")

bus.write_block_data(
    0x19, 13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2])
block = bus.read_i2c_block_data(0x19, 11, 9)
assert block == [8, 1, 2, 3, 4, 5, 6, 7, 8]
print("Write/Read block OK")
Пример #8
0
class InputModule(AbstractInput):
    """ A sensor support class that monitors the DS18B20's lux """
    def __init__(self, input_dev, testing=False):
        super(InputModule, self).__init__()
        self.logger = logging.getLogger("mycodo.inputs.bh1750")
        self._lux = None

        if not testing:
            from smbus2 import SMBus
            self.logger = logging.getLogger("mycodo.bh1750_{id}".format(
                id=input_dev.unique_id.split('-')[0]))
            self.i2c_address = int(str(input_dev.i2c_location), 16)
            self.i2c_bus = input_dev.i2c_bus
            self.resolution = input_dev.resolution
            self.sensitivity = input_dev.sensitivity
            self.convert_to_unit = input_dev.convert_to_unit
            self.i2c_bus = SMBus(self.i2c_bus)
            self.power_down()
            self.set_sensitivity(sensitivity=self.sensitivity)

    def __repr__(self):
        """  Representation of object """
        return "<{cls}(lux={lux})>".format(cls=type(self).__name__,
                                           lux="{0:.2f}".format(self._lux))

    def __str__(self):
        """ Return lux information """
        return "Lux: {lux}".format(lux="{0:.2f}".format(self._lux))

    def __iter__(self):  # must return an iterator
        """ BH1750Sensor iterates through live lux readings """
        return self

    def next(self):
        """ Get next lux reading """
        if self.read():  # raised an error
            raise StopIteration  # required
        return dict(lux=float('{0:.2f}'.format(self._lux)))

    @property
    def lux(self):
        """ BH1750 luminosity in lux """
        if self._lux is None:  # update if needed
            self.read()
        return self._lux

    def get_measurement(self):
        """ Gets the BH1750's lux """
        self._lux = None

        if self.resolution == 0:
            lux = self.measure_low_res()
        elif self.resolution == 1:
            lux = self.measure_high_res()
        elif self.resolution == 2:
            lux = self.measure_high_res2()
        else:
            return None

        lux = convert_units('light', 'lux', self.convert_to_unit, lux)

        return lux

    def read(self):
        """
        Takes a reading from the BH1750 and updates the self._lux value

        :returns: None on success or 1 on error
        """
        try:
            self._lux = self.get_measurement()
            if self._lux is not None:
                return  # success - no errors
        except Exception as e:
            self.logger.exception(
                "{cls} raised an exception when taking a reading: "
                "{err}".format(cls=type(self).__name__, err=e))
        return 1

    def _set_mode(self, mode):
        self.mode = mode
        self.i2c_bus.write_byte(self.i2c_address, self.mode)

    def power_down(self):
        self._set_mode(POWER_DOWN)

    def power_on(self):
        self._set_mode(POWER_ON)

    def reset(self):
        self.power_on()  # It has to be powered on before resetting
        self._set_mode(RESET)

    def cont_low_res(self):
        self._set_mode(CONTINUOUS_LOW_RES_MODE)

    def cont_high_res(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_1)

    def cont_high_res2(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_2)

    def oneshot_low_res(self):
        self._set_mode(ONE_TIME_LOW_RES_MODE)

    def oneshot_high_res(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_1)

    def oneshot_high_res2(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_2)

    def set_sensitivity(self, sensitivity=69):
        """
        Set the sensor sensitivity.
        Valid values are 31 (lowest) to 254 (highest), default is 69.
        """
        if sensitivity < 31:
            self.mtreg = 31
        elif sensitivity > 254:
            self.mtreg = 254
        else:
            self.mtreg = sensitivity
        self.power_on()
        self._set_mode(0x40 | (self.mtreg >> 5))
        self._set_mode(0x60 | (self.mtreg & 0x1f))
        self.power_down()

    def get_result(self):
        """ Return current measurement result in lx. """
        data = self.i2c_bus.read_word_data(self.i2c_address, self.mode)
        count = data >> 8 | (data & 0xff) << 8
        mode2coeff = 2 if (self.mode & 0x03) == 0x01 else 1
        ratio = 1 / (1.2 * (self.mtreg / 69.0) * mode2coeff)
        return ratio * count

    def wait_for_result(self, additional=0):
        basetime = 0.018 if (self.mode & 0x03) == 0x03 else 0.128
        time.sleep(basetime * (self.mtreg / 69.0) + additional)

    def do_measurement(self, mode, additional_delay=0):
        """
        Perform complete measurement using command specified by parameter
        mode with additional delay specified in parameter additional_delay.
        Return output value in Lx.
        """
        self.reset()
        self._set_mode(mode)
        self.wait_for_result(additional=additional_delay)
        return self.get_result()

    def measure_low_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_LOW_RES_MODE, additional_delay)

    def measure_high_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_1, additional_delay)

    def measure_high_res2(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_2, additional_delay)
Пример #9
0
class INA233:
    
    CLEAR_FAULTS         = 0x03
    RESTORE_DEFAULT_ALL  = 0x12
    CAPABILITY           = 0x19
    IOUT_OC_WARN_LIMIT   = 0x4A
    VIN_OV_WARN_LIMIT    = 0x57
    VIN_UV_WARN_LIMIT    = 0x58
    PIN_OP_WARN_LIMIT    = 0x6B
    STATUS_BYTE          = 0x78
    STATUS_WORD          = 0x79
    STATUS_IOUT          = 0x79
    STATUS_IOUT          = 0x7B
    STATUS_INPUT         = 0x7C
    STATUS_CML           = 0x7E
    STATUS_MFR_SPECIFIC  = 0x80
    READ_EIN             = 0x86
    READ_VIN             = 0x88
    READ_IIN             = 0x89
    READ_VOUT            = 0x8B
    READ_IOUT            = 0x8C
    READ_POUT            = 0x96
    READ_PIN             = 0x97
    MFR_ID               = 0x99
    MFR_MODEL            = 0x9A
    MFR_REVISION         = 0x9B
    MFR_ADC_CONFIG       = 0xD0
    MFR_READ_VSHUNT      = 0xD1
    MFR_ALERT_MASK       = 0xD2
    MFR_CALIBRATION      = 0xD4
    MFR_DEVICE_CONFIG    = 0xD5
    CLEAR_EIN            = 0xD6
    TI_MFR_ID            = 0xE0
    TI_MFR_MODEL         = 0xE1
    TI_MFR_REVISION      = 0xE2
    
    # from table 1 p 17 of INA233 documentation pdf
    #SHUNT VOLTAGE TELEMETRY & WARNING COEFFICIENTS
    _m_vs = 4
    _R_vs = 5
    _b_vs = 0
    
    _m_c =0
    _R_c = 0
    _m_p = 0
    _R_p = 0
    
    #BUS VOLTAGE TELEMETRY & WARNING COEFFICIENTS
    _R_vb = 2
    _b_vb = 0
    _m_vb = 8
    
    # CURRENT & POWER CONSTANT TELEMETRY & WARNING COEFFICIENTS
    _b_c = 0
    _b_p = 0
    
    _BUS_MILLIVOLTS_LSB = 0.00125
    _SHUNT_MILLIVOLTS_LSB = 0.0000025

    _accumulator_24 = 0
    _sample_count = 0

    def __init__(self, bus, address): 
        self._bus = SMBus(bus)
        self._address = address

    def calibrate(self, R_shunt, I_max):
        """ Calibration and scaling values per section 7.5.2
        of TI INA233 datasheet
        """
        self._R_shunt = R_shunt
        self._I_max = I_max
        self._Current_LSB = 0
        self._Power_LSB = 0
        self._CAL = 0
        tmp = 0
        round_done = False
        ERROR = 0
    
        self._Current_LSB=self._I_max/(pow(2,15))
        self._Power_LSB=25*self._Current_LSB
        self._CAL=0.00512/(self._R_shunt*self._Current_LSB)
    
        #check if CAL is in the uint16 range
        if self._CAL>0xFFFF:
            ERROR=1
        else:
            self._bus.write_word_data(self._address,self.MFR_CALIBRATION,int(self._CAL))
    
        self._m_c=1/self._Current_LSB
        self._m_p=1/self._Power_LSB
    
        #Calculate m and R for maximum accuracy in current measurement
        tmp=int(self._m_c)
        while ((tmp > 32768) or (tmp < -32768)):
            self._m_c=self._m_c/10
            self._R_c = self._R_c + 1
            tmp=int(self._m_c)
    
        while round_done==False:
            tmp=int(self._m_c)
            if tmp==self._m_c:
                round_done=True
            else:
                tmp=int(self._m_c*10)             #shift decimal to the right
                if ((tmp>32768) or (tmp<-32768)):       #m_c is out of int16 (-32768 to 32768)
                    round_done=True
                else:
                    self._m_c=self._m_c*10
                    self._R_c = self._R_c - 1 
        round_done=False
        #Calculate m and R for maximum accuracy in power measurement
        tmp = int(self._m_p)
        while tmp>32768 or tmp<-32768:
            self._m_p=self._m_p/10
            self._R_p = self._R_p + 1
            tmp = int(self._m_p)
        while round_done == False:
            tmp = int(self._m_p)
            if tmp==self._m_p:
                round_done=True
            else:
                tmp = int(self._m_p*10)          #shift decimal to the right
                if tmp>32768 or tmp<-32768:       #m_p is out of int16 (-32768 to 32768)
                    round_done=True
                else:
                    self._m_p = self._m_p*10
                    self._R_p = self._R_p - 1
    
        self._m_c = int(self._m_c)
        self._m_p = int(self._m_p)
    
    def _getBusVoltageIn_raw(self):
        raw_read =  self._bus.read_word_data(self._address, self.READ_VIN)
        return int(raw_read)
    
    def _getBusVoltageOut_raw(self):
        raw_read =  self._bus.read_word_data(self._address, self.READ_VOUT)
        return int(raw_read)
    
    def _getShuntVoltage_raw(self):
        raw_read =  self._bus.read_word_data(self._address, self.MFR_READ_VSHUNT)
        return int(raw_read)
    
    def _getCurrentOut_raw(self):
        raw_read =  self._bus.read_i2c_block_data(self._address, self.READ_IOUT, 2)
        return raw_read[0] * 256 + raw_read[1]
    
    def _getCurrentIn_raw(self):
        raw_read = self._bus.read_i2c_block_data(self._address, self.READ_IIN, 2)
        return raw_read[0] * 256 + raw_read[1]
    
    def getShuntVoltage_mV(self):
        raw_read = self._getShuntVoltage_raw()
        #return ((raw_read*pow(10,-self._R_vs)-self._b_vs)/self._m_vs)
        return raw_read * self._SHUNT_MILLIVOLTS_LSB * 1000
    
    def getBusVoltageIn_V(self):
        raw_read = self._getBusVoltageIn_raw()
        #return ((raw_read*pow(10,-self._R_vb)-self._b_vb)/self._m_vb)
        return raw_read * self._BUS_MILLIVOLTS_LSB
    
    def getBusVoltageOut_V(self):
        raw_read = self._getBusVoltageOut_raw()
        #return ((raw_read*pow(10,-self._R_vb)-self._b_vb)/self._m_vb)
        return raw_read * self._BUS_MILLIVOLTS_LSB
    
    def getCurrentIn_mA(self):
        word_rdata=self._getCurrentIn_raw()
        current_twos_compliment = word_rdata
        current_sign_bit = current_twos_compliment >> 15
        if(current_sign_bit == 1):
            current = float(self._twos_compliment_to_int(current_twos_compliment, 16)) * self._Current_LSB
        else:
            #current =(value*(pow(10,-self._R_c))-self._b_c)/self._m_c
            current = float(current_twos_compliment) * self._Current_LSB
        return current
    
    def getCurrentOut_mA(self):
        word_rdata=self._getCurrentOut_raw()
        current_twos_compliment = word_rdata
        current_sign_bit = current_twos_compliment >> 15
        if(current_sign_bit == 1):
            current = float(self._twos_compliment_to_int(current_twos_compliment, 16)) * self._Current_LSB
        else:
            #current =(value*(pow(10,-self._R_c))-self._b_c)/self._m_c
            current = float(current_twos_compliment) * self._Current_LSB
        return current 
    
    def _getPower_raw(self):
        raw_read = self._bus.read_word_data(self._address, self.READ_PIN)
        return int(raw_read)
    
    def _getEnergy_raw(self):
        raw_read = self._bus.read_i2c_block_data(self._address,self.READ_EIN,6)
        self._accumulator=(raw_read[0] << 8) |  raw_read[1]
        self._roll_over=raw_read[2]
        self._sample_count=raw_read[5]<< 16
        self._sample_count=(raw_read[4]<< 8) | self._sample_count
        self._sample_count=(raw_read[3] |  self._sample_count)
    
    def getAv_Power_mW(self):
        raw_av_power=0
        av_power=0
#        prev_accumulator_24 = self._accumulator_24
#        prev_sample_count = self._sample_count
        self._getEnergy_raw()
        #Total Accumulated Unscaled Power (Accumulator_24) = (rollover_count × 2^16) + Accumulator
        self._accumulator_24=int(self._roll_over)*65536+int(self._accumulator)
#        raw_av_power=(self._accumulator_24-prev_accumulator_24)/(self._sample_count-prev_sample_count)
        # doing it this way may be less accurate, but it avoids the divide by zero in the first reading
        raw_av_power=(self._accumulator_24)/(self._sample_count)
        #av_power=(raw_av_power*pow(10,-self._R_p)-self._b_p)/self._m_p
        av_power = raw_av_power * self._Power_LSB
        return av_power * 1000
    
    def getPower_mW(self):
        raw_read=self._getPower_raw()
        #power =(raw_read*pow(10,-self._R_p)-self._b_p)/self._m_p
        power = raw_read * self._Power_LSB
        return power 

    def _twos_compliment_to_int(self, val, bits):
        if (val & (1 << (bits - 1))) != 0:
            val = val - (1 << bits)
        return val
config_reg = 0x01
config = 0b1100111000000000
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
data_file = open("sensor_data.dat", "w")
data_file.write(
    "YYYY-MM-DD HH:mm:ss.ffffff,lux,b'r,mag/arcsec^2,Hz,idk,idk,Celcius,GPS\n")

print(hex(config))
i2c = SMBus(1)
#i2c.write_word_data(i2c_addr, config_reg, config)
i2c.write_i2c_block_data(i2c_addr, config_reg, [0b11001110, 0b00000000])
for byte in i2c.read_i2c_block_data(i2c_addr, 0x7E, 2):
    print(hex(byte))
for byte in i2c.read_i2c_block_data(i2c_addr, 0x7F, 2):
    print(hex(byte))
print(hex(i2c.read_word_data(i2c_addr, config_reg)))

while (1):
    conversion_ready = i2c.read_word_data(i2c_addr, config_reg)
    if ((conversion_ready & 0x80) == 0x80):
        reading = i2c.read_word_data(i2c_addr, result_reg)
        lux = 0.01 * (1 << ((reading & 0xF000) >> 12)) * (reading & 0x0FFF)
        ser.write(b'rx')
        sqm = ser.readline()
        print("Luminance Reading: ", end='')
        print(lux, end=' ')
        print("lux")
        print("SQM Reading: ", end='')
        print(sqm, end=' ')
        now = datetime.now()
        data_file.write(str(now))
Пример #11
0
 def read_word_data(self, *args, **kwargs):
     """Overridden :method:`read_word_data` from :class:`SMBus` without I2C address parameter."""
     return SMBus.read_word_data(self, self.device_addr, *args, **kwargs)
Пример #12
0
class InputModule(AbstractInput):
    """
    A sensor support class that measures the Chirp's moisture, temperature
    and light

    """

    def __init__(self, input_dev, testing=False):
        super(InputModule, self).__init__()
        self.logger = logging.getLogger("mycodo.inputs.chirp")
        self._lux = None
        self._moisture = None
        self._temperature = None

        if not testing:
            self.logger = logging.getLogger(
                "mycodo.chirp_{id}".format(id=input_dev.unique_id.split('-')[0]))
            self.i2c_address = int(str(input_dev.i2c_location), 16)
            self.i2c_bus = input_dev.i2c_bus
            self.convert_to_unit = input_dev.convert_to_unit
            self.bus = SMBus(self.i2c_bus)
            self.filter_average('lux', init_max=3)

    def __repr__(self):
        """  Representation of object """
        return "<{cls}(lux={lux})(moisture={moist})(temperature={temp})>".format(
            cls=type(self).__name__,
            lux="{0}".format(self._lux),
            moist="{0}".format(self._moisture),
            temp="{0:.2f}".format(self._temperature))

    def __str__(self):
        """ Return measurement information """
        return "Light: {lux}, Moisture: {moist}, Temperature: {temp}".format(
            lux="{0}".format(self._lux),
            moist="{0}".format(self._moisture),
            temp="{0:.2f}".format(self._temperature))

    def __iter__(self):  # must return an iterator
        """ ChirpSensor iterates through live measurement readings """
        return self

    def next(self):
        """ Get next measurement reading """
        if self.read():  # raised an error
            raise StopIteration  # required
        return dict(lux=float('{0}'.format(self._lux)),
                    moisture=float('{0}'.format(self._moisture)),
                    temperature=float('{0:.2f}'.format(self._temperature)))

    @property
    def lux(self):
        """ Chirp light measurement """
        if self._lux is None:  # update if needed
            self.read()
        return self._lux

    @property
    def moisture(self):
        """ Chirp moisture measurement """
        if self._moisture is None:  # update if needed
            self.read()
        return self._moisture

    @property
    def temperature(self):
        """ Chirp temperature in Celsius """
        if self._temperature is None:  # update if needed
            self.read()
        return self._temperature

    def get_measurement(self):
        """ Gets the light, moisture, and temperature """
        self._lux = None
        self._moisture = None
        self._temperature = None

        lux = self.filter_average('lux', measurement=self.light())
        lux = convert_units(
            'light', 'lux', self.convert_to_unit,
            lux)

        moisture = self.moist()

        temperature = convert_units(
            'temperature', 'C', self.convert_to_unit,
            self.temp() / 10.0)

        return lux, moisture, temperature

    def read(self):
        """
        Takes a reading from the AM2315 and updates the self.dew_point,
        self._humidity, and self._temperature values

        :returns: None on success or 1 on error
        """
        try:
            self._lux, self._moisture, self._temperature = self.get_measurement()
            if self._lux is not None:
                return  # success - no errors
        except Exception as e:
            self.logger.exception(
                "{cls} raised an exception when taking a reading: "
                "{err}".format(cls=type(self).__name__, err=e))
        return 1

    def get_reg(self, reg):
        # read 2 bytes from register
        val = self.bus.read_word_data(self.i2c_address, reg)
        # return swapped bytes (they come in wrong order)
        return (val >> 8) + ((val & 0xFF) << 8)

    def reset(self):
        # To reset the sensor, write 6 to the device I2C address
        self.bus.write_byte(self.i2c_address, 6)

    def set_addr(self, new_addr):
        # To change the I2C address of the sensor, write a new address
        # (one byte [1..127]) to register 1; the new address will take effect after reset
        self.bus.write_byte_data(self.i2c_address, 1, new_addr)
        self.reset()
        # self.address = new_addr

    def moist(self):
        # To read soil moisture, read 2 bytes from register 0
        return self.get_reg(0)

    def temp(self):
        # To read temperature, read 2 bytes from register 5
        return self.get_reg(5)

    def light(self):
        # To read light level, start measurement by writing 3 to the
        # device I2C address, wait for 3 seconds, read 2 bytes from register 4
        self.bus.write_byte(self.i2c_address, 3)
        time.sleep(1.5)
        lux = self.get_reg(4)
        if lux == 0:
            return 65535.0
        else:
            return(1 - (lux / 65535.0)) * 65535.0
Пример #13
0
class Device(object):
    """Class for communicating with an I2C device using the smbus library.
    Allows reading and writing 8-bit, 16-bit, and byte array values to registers
    on the device."""
    def __init__(self, address, busnum):
        """Create an instance of the I2C device at the specified address on the
        specified I2C bus number."""
        self._address = address
        self._bus = SMBus(busnum)

    def writeRaw8(self, value):
        """Write an 8-bit value on the bus (without register)."""
        value = value & 0xFF
        self._bus.write_byte(self._address, value)

    def write8(self, register, value):
        """Write an 8-bit value to the specified register."""
        value = value & 0xFF
        self._bus.write_byte_data(self._address, register, value)

    def write16(self, register, value):
        """Write a 16-bit value to the specified register."""
        value = value & 0xFFFF
        self._bus.write_word_data(self._address, register, value)

    def writeList(self, register, data):
        """Write bytes to the specified register."""
        self._bus.write_i2c_block_data(self._address, register, data)

    def readList(self, register, length):
        """Read a length number of bytes from the specified register.  Results
        will be returned as a bytearray."""
        results = self._bus.read_i2c_block_data(self._address, register,
                                                length)
        return results

    def readRaw8(self):
        """Read an 8-bit value on the bus (without register)."""
        result = self._bus.read_byte(self._address) & 0xFF
        return result

    def readU8(self, register):
        """Read an unsigned byte from the specified register."""
        result = self._bus.read_byte_data(self._address, register) & 0xFF
        return result

    def readS8(self, register):
        """Read a signed byte from the specified register."""
        result = self.readU8(register)
        if result > 127:
            result -= 256
        return result

    def readU16(self, register, little_endian=True):
        """Read an unsigned 16-bit value from the specified register, with the
        specified endianness (default little endian, or least significant byte
        first)."""
        result = self._bus.read_word_data(self._address, register) & 0xFFFF
        # Swap bytes if using big endian because read_word_data assumes little
        # endian on ARM (little endian) systems.
        if not little_endian:
            result = ((result << 8) & 0xFF00) + (result >> 8)
        return result

    def readS16(self, register, little_endian=True):
        """Read a signed 16-bit value from the specified register, with the
        specified endianness (default little endian, or least significant byte
        first)."""
        result = self.readU16(register, little_endian)
        if result > 32767:
            result -= 65536
        return result

    def readU16LE(self, register):
        """Read an unsigned 16-bit value from the specified register, in little
        endian byte order."""
        return self.readU16(register, little_endian=True)

    def readU16BE(self, register):
        """Read an unsigned 16-bit value from the specified register, in big
        endian byte order."""
        return self.readU16(register, little_endian=False)

    def readS16LE(self, register):
        """Read a signed 16-bit value from the specified register, in little
        endian byte order."""
        return self.readS16(register, little_endian=True)

    def readS16BE(self, register):
        """Read a signed 16-bit value from the specified register, in big
        endian byte order."""
        return self.readS16(register, little_endian=False)
Пример #14
0
class BMP280():
    BMP280_ADDR = 0x76

    t_fine = 0

    DIG_T1 = 0x88
    DIG_T2 = 0x8A
    DIG_T3 = 0x8C

    DIG_P1 = 0x8E
    DIG_P2 = 0x90
    DIG_P3 = 0x92
    DIG_P4 = 0x94
    DIG_P5 = 0x96
    DIG_P6 = 0x98
    DIG_P7 = 0x9A
    DIG_P8 = 0x9C
    DIG_P9 = 0x9E

    DEVICE_ID = 0xD0
    RESET = 0xE0
    STATUS = 0xF3
    CTRL_MEAS = 0xF4
    CONFIG = 0xF5
    PRESSURE = 0xF7
    TEMPERATURE = 0xFA

    RESET_CMD = 0xB6

    OVERSAMPLING_P_NONE = 0b000
    OVERSAMPLING_P_x1 = 0b001
    OVERSAMPLING_P_x2 = 0b010
    OVERSAMPLING_P_x4 = 0b011
    OVERSAMPLING_P_x8 = 0b100
    OVERSAMPLING_P_x16 = 0b101

    OVERSAMPLING_T_NONE = 0b000
    OVERSAMPLING_T_x1 = 0b001
    OVERSAMPLING_T_x2 = 0b010
    OVERSAMPLING_T_x4 = 0b011
    OVERSAMPLING_T_x8 = 0b100
    OVERSAMPLING_T_x16 = 0b101

    T_STANDBY_0p5 = 0b000
    T_STANDBY_62p5 = 0b001
    T_STANDBY_125 = 0b010
    T_STANDBY_250 = 0b011
    T_STANDBY_500 = 0b100
    T_STANDBY_1000 = 0b101
    T_STANDBY_2000 = 0b110
    T_STANDBY_4000 = 0b111

    IIR_FILTER_OFF = 0b000
    IIR_FILTER_x2 = 0b001
    IIR_FILTER_x4 = 0b010
    IIR_FILTER_x8 = 0b011
    IIR_FILTER_x16 = 0b100

    SLEEP_MODE = 0b00
    FORCED_MODE = 0b01
    NORMAL_MODE = 0b11

    def __init__(self,
                 port=1,
                 mode=FORCED_MODE,
                 oversampling_p=OVERSAMPLING_P_x16,
                 oversampling_t=OVERSAMPLING_T_x1,
                 filter=IIR_FILTER_OFF,
                 standby=T_STANDBY_4000):
        self.bus = SMBus(port)
        self.bmp280_init(mode, oversampling_p, oversampling_t, filter, standby)

    def read_device_id(self):
        return self.bus.read_byte_data(self.BMP280_ADDR, self.DEVICE_ID)

    def device_reset(self):
        self.bus.write_byte_data(self.BMP280_ADDR, self.RESET, self.RESET_CMD)
        sleep(1)

    def bmp280_init(self, mode, oversampling_p, oversampling_t, filter,
                    standby):
        ctrl_meas_reg = mode + (oversampling_p << 2) + (oversampling_t << 5)
        self.bus.write_byte_data(self.BMP280_ADDR, self.CTRL_MEAS,
                                 ctrl_meas_reg)

        config_reg = 0b000 + (filter << 2) + (standby << 5)
        self.bus.write_byte_data(self.BMP280_ADDR, self.CONFIG, config_reg)

    def read_temperature(self):
        t1 = self.bus.read_word_data(self.BMP280_ADDR, self.DIG_T1)
        t2 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_T2))
        t3 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_T3))

        raw_data = self.bus.read_i2c_block_data(self.BMP280_ADDR,
                                                self.TEMPERATURE, 3)
        adc_t = (raw_data[0] * pow(2, 16) + raw_data[1] * pow(2, 8) +
                 raw_data[2]) >> 4

        var1 = ((adc_t / 16384.0) - (t1 / 1024.0)) * t2
        var2 = ((adc_t / 131072.0) - (t1 / 8192.0)) * (((adc_t / 131072.0) -
                                                        (t1 / 8192.0)) * t3)
        self.t_fine = var1 + var2
        return (var1 + var2) / 5120.0

    def read_pressure(self):
        p1 = self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P1)
        p2 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P2))
        p3 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P3))
        p4 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P4))
        p5 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P5))
        p6 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P6))
        p7 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P7))
        p8 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P8))
        p9 = twos_complement(
            self.bus.read_word_data(self.BMP280_ADDR, self.DIG_P9))

        raw_data = self.bus.read_i2c_block_data(self.BMP280_ADDR,
                                                self.PRESSURE, 3)
        adc_p = (raw_data[0] * pow(2, 16) + raw_data[1] * pow(2, 8) +
                 raw_data[2]) >> 4

        self.read_temperature()

        var1 = (self.t_fine / 2.0) - 64000.0
        var2 = var1 * var1 * p6 / 32768.0
        var2 += var1 * p5 * 2.0
        var2 = (var2 / 4.0) + (p4 * 65536.0)
        var1 = (p3 * var1 * var1 / 524288.0 + (p2 * var1)) / 524288.0
        var1 = (1.0 + (var1 / 32768.0)) * p1
        p = 1048576.0 - adc_p
        p = (p - (var2 / 4096.0)) * 6250.0 / var1
        var1 = p9 * p * p / 2147483648.0
        var2 = p * p8 / 32768.0
        p += (var1 + var2 + p7) / 16.0
        return p / 100
Пример #15
0
# ---- Battery SMBUS ---- #
bus = SMBus(1)  #SMBUS init

addr = 0x0b  #SMBUS Address
serial = ""
cycle = ""
failedcycles = 0

#Exit when data is not being pulled from smbus
while cycle == "":
    print failedcycles
    if failedcycles == 13:
        print "SMBus is broken/diconnected"
        exit()
    try:
        serial = str(bus.read_word_data(addr, 0x1c))  #Serial Number
        cycle = str(bus.read_word_data(addr, 0x17))  # Cycle Count

    except IOError:
        print "Could not connect to bus"
        time.sleep(1)
        failedcycles += 1

# ---- MySQL data table init ---- #

table = raw_input("Make a new table name: ")
addtable = "CREATE TABLE " + str(
    table
) + "(time DECIMAL(20,2), temperature NUMERIC, voltage NUMERIC, current NUMERIC, relsoc NUMERIC, abssoc NUMERIC, ttoempty NUMERIC,remcap NUMERIC, fullcap NUMERIC, changecurr NUMERIC, changevolt NUMERIC, maxerror NUMERIC);"

# ---- Table Management ---- #
Пример #16
0
class InputModule(AbstractInput):
    """ A sensor support class that monitors the DS18B20's lux """
    def __init__(self, input_dev, testing=False):
        super(InputModule, self).__init__()
        self.logger = logging.getLogger("mycodo.inputs.bh1750")

        if not testing:
            from smbus2 import SMBus
            self.logger = logging.getLogger(
                "mycodo.bh1750_{id}".format(id=input_dev.unique_id.split('-')[0]))

            self.device_measurements = db_retrieve_table_daemon(
                DeviceMeasurements).filter(
                    DeviceMeasurements.device_id == input_dev.unique_id)

            self.i2c_address = int(str(input_dev.i2c_location), 16)
            self.resolution = input_dev.resolution
            self.sensitivity = input_dev.sensitivity
            self.i2c_bus = SMBus(input_dev.i2c_bus)
            self.power_down()
            self.set_sensitivity(sensitivity=self.sensitivity)

    @property
    def lux(self):
        """ BH1750 luminosity in lux """
        if self._measurements is None:  # update if needed
            self.read()
        return self._measurements

    def get_measurement(self):
        """ Gets the BH1750's lux """
        return_dict = measurements_dict.copy()

        if self.resolution == 0:
            lux = self.measure_low_res()
        elif self.resolution == 1:
            lux = self.measure_high_res()
        elif self.resolution == 2:
            lux = self.measure_high_res2()
        else:
            return None

        return_dict[0]['value'] = lux

        return return_dict

    def _set_mode(self, mode):
        self.mode = mode
        self.i2c_bus.write_byte(self.i2c_address, self.mode)

    def power_down(self):
        self._set_mode(POWER_DOWN)

    def power_on(self):
        self._set_mode(POWER_ON)

    def reset(self):
        self.power_on()  # It has to be powered on before resetting
        self._set_mode(RESET)

    def cont_low_res(self):
        self._set_mode(CONTINUOUS_LOW_RES_MODE)

    def cont_high_res(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_1)

    def cont_high_res2(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_2)

    def oneshot_low_res(self):
        self._set_mode(ONE_TIME_LOW_RES_MODE)

    def oneshot_high_res(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_1)

    def oneshot_high_res2(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_2)

    def set_sensitivity(self, sensitivity=69):
        """
        Set the sensor sensitivity.
        Valid values are 31 (lowest) to 254 (highest), default is 69.
        """
        if sensitivity < 31:
            self.mtreg = 31
        elif sensitivity > 254:
            self.mtreg = 254
        else:
            self.mtreg = sensitivity
        self.power_on()
        self._set_mode(0x40 | (self.mtreg >> 5))
        self._set_mode(0x60 | (self.mtreg & 0x1f))
        self.power_down()

    def get_result(self):
        """ Return current measurement result in lx. """
        data = self.i2c_bus.read_word_data(self.i2c_address, self.mode)
        count = data >> 8 | (data & 0xff) << 8
        mode2coeff = 2 if (self.mode & 0x03) == 0x01 else 1
        ratio = 1 / (1.2 * (self.mtreg / 69.0) * mode2coeff)
        return ratio * count

    def wait_for_result(self, additional=0):
        basetime = 0.018 if (self.mode & 0x03) == 0x03 else 0.128
        time.sleep(basetime * (self.mtreg / 69.0) + additional)

    def do_measurement(self, mode, additional_delay=0):
        """
        Perform complete measurement using command specified by parameter
        mode with additional delay specified in parameter additional_delay.
        Return output value in Lx.
        """
        self.reset()
        self._set_mode(mode)
        self.wait_for_result(additional=additional_delay)
        return self.get_result()

    def measure_low_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_LOW_RES_MODE, additional_delay)

    def measure_high_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_1, additional_delay)

    def measure_high_res2(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_2, additional_delay)
class i2c_device:
    # Bit masks.
    bit0 = 0x01
    bit1 = 0x02
    bit2 = 0x04
    bit3 = 0x08
    bit4 = 0x10
    bit5 = 0x20
    bit6 = 0x40
    bit7 = 0x80

    def __init__(self, address=None, bus=None):
        self.address = address  # "address" is the device address on the i2c bus.
        self.bus = bus
        self.DEBUG = 0
        if self.bus == None:
            self.bus = DEFAULT_I2C_BUS
            # "bus" is the Raspberry Pi external i2c bus, where the MCP23017 is connected.
            # This may vary accross different Raspberry Pi models.  0 is used by the
            # original Raspbery Pi model B (256 MB memory, 26-pin GPIO connector).
            # 1 is used by recent Raspberry Pi devices.
        self.device = SMBus(self.bus)
        return

    def bus_reset(self):
        '''Caution:  bus reset is a general call operation.  It
is not device-specific.  All devices on the bus are affected.
In systems with multiple i2c busses, only one bus (the bus associated
with this device) is reset.'''
        self.device.write_byte(0, 6)
        return

    def wbyte_only(self, value):
        # Write a single byte to device, without any register address.
        self.device.write_byte(self.address, value)

    def rbyte_only(self):
        # Read a single byte from device, without any register address.
        return self.device.read_byte(self.address)

    def wbyte(self, reg, value):
        # Write a single byte <value> to register <reg>.
        if self.DEBUG >= 32:
            sys.stdout.write(
                '  write  x{:02X} to chip x{:02X} register {}\n'.format(
                    value, self.address, reg))
            sys.flush()
        self.device.write_byte_data(self.address, reg, value)
        return

    def rbyte(self, reg):
        # Read one byte from register <reg>.
        return self.device.read_byte_data(self.address, reg)

    def wword(self, reg, value):
        '''Write the integer <value> (two bytes) to register <reg>.'''
        if byte_swap:
            value = ((value & 0xff) << 8) | ((value >> 8) & 0xff)
        self.device.write_word_data(self.address, reg, value)
        return

    def rword(self, reg):
        value = self.device.read_word_data(self.address, reg)
        if byte_swap:
            value = ((value & 0xff) << 8) | ((value >> 8) & 0xff)
        return value
Пример #18
0
class InputModule(AbstractInput):
    """A sensor support class that monitors the DS18B20's lux."""
    def __init__(self, input_dev, testing=False):
        super().__init__(input_dev, testing=testing, name=__name__)

        self.i2c_address = None
        self.i2c_bus = None
        self.resolution = None

        if not testing:
            self.try_initialize()

    def initialize(self):
        from smbus2 import SMBus

        self.i2c_address = int(str(self.input_dev.i2c_location), 16)
        self.resolution = self.input_dev.resolution
        self.i2c_bus = SMBus(self.input_dev.i2c_bus)
        self.power_down()
        self.set_sensitivity(sensitivity=self.input_dev.sensitivity)

    @property
    def lux(self):
        """BH1750 luminosity in lux."""
        if self._measurements is None:  # update if needed
            self.read()
        return self._measurements

    def get_measurement(self):
        """Gets the BH1750's lux."""
        self.return_dict = copy.deepcopy(measurements_dict)

        if self.resolution == 0:
            lux = self.measure_low_res()
        elif self.resolution == 1:
            lux = self.measure_high_res()
        elif self.resolution == 2:
            lux = self.measure_high_res2()
        else:
            return None

        self.value_set(0, lux)

        return self.return_dict

    def _set_mode(self, mode):
        self.mode = mode
        self.i2c_bus.write_byte(self.i2c_address, self.mode)

    def power_down(self):
        self._set_mode(POWER_DOWN)

    def power_on(self):
        self._set_mode(POWER_ON)

    def reset(self):
        self.power_on()  # It has to be powered on before resetting
        self._set_mode(RESET)

    def cont_low_res(self):
        self._set_mode(CONTINUOUS_LOW_RES_MODE)

    def cont_high_res(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_1)

    def cont_high_res2(self):
        self._set_mode(CONTINUOUS_HIGH_RES_MODE_2)

    def oneshot_low_res(self):
        self._set_mode(ONE_TIME_LOW_RES_MODE)

    def oneshot_high_res(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_1)

    def oneshot_high_res2(self):
        self._set_mode(ONE_TIME_HIGH_RES_MODE_2)

    def set_sensitivity(self, sensitivity=69):
        """
        Set the sensor sensitivity.
        Valid values are 31 (lowest) to 254 (highest), default is 69.
        """
        if sensitivity < 31:
            self.mtreg = 31
        elif sensitivity > 254:
            self.mtreg = 254
        else:
            self.mtreg = sensitivity
        self.power_on()
        self._set_mode(0x40 | (self.mtreg >> 5))
        self._set_mode(0x60 | (self.mtreg & 0x1f))
        self.power_down()

    def get_result(self):
        """Return current measurement result in lux."""
        data = self.i2c_bus.read_word_data(self.i2c_address, self.mode)
        count = data >> 8 | (data & 0xff) << 8
        mode2coeff = 2 if (self.mode & 0x03) == 0x01 else 1
        ratio = 1 / (1.2 * (self.mtreg / 69.0) * mode2coeff)
        return ratio * count

    def wait_for_result(self, additional=0):
        basetime = 0.018 if (self.mode & 0x03) == 0x03 else 0.128
        time.sleep(basetime * (self.mtreg / 69.0) + additional)

    def do_measurement(self, mode, additional_delay=0):
        """
        Perform complete measurement using command specified by parameter
        mode with additional delay specified in parameter additional_delay.
        Return output value in Lx.
        """
        self.reset()
        self._set_mode(mode)
        self.wait_for_result(additional=additional_delay)
        return self.get_result()

    def measure_low_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_LOW_RES_MODE, additional_delay)

    def measure_high_res(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_1, additional_delay)

    def measure_high_res2(self, additional_delay=0):
        return self.do_measurement(ONE_TIME_HIGH_RES_MODE_2, additional_delay)
Пример #19
0
class I2CUnifiedLinux(I2CBase):
    def __init__(self, bus=None):
        if bus is None:
            bus = 1
        self.i2c = SMBus(bus)

    def readfrom_mem(self, addr, memaddr, nbytes, *, addrsize=8):
        data = [None] * nbytes  # initialise empty list
        self.smbus_i2c_read(addr, memaddr, data, nbytes, addrsize=addrsize)
        return data

    def writeto_mem(self, addr, memaddr, buf, *, addrsize=8):
        self.smbus_i2c_write(addr, memaddr, buf, len(buf), addrsize=addrsize)

    def smbus_i2c_write(self, address, reg, data_p, length, addrsize=8):
        ret_val = 0
        data = []
        for index in range(length):
            data.append(data_p[index])
        if addrsize == 8:
            msg_w = i2c_msg.write(address, [reg] + data)
        elif addrsize == 16:
            msg_w = i2c_msg.write(address, [reg >> 8, reg & 0xff] + data)
        else:
            raise Exception("address must be 8 or 16 bits long only")
        self.i2c.i2c_rdwr(msg_w)
        return ret_val

    def smbus_i2c_read(self, address, reg, data_p, length, addrsize=8):
        ret_val = 0
        if addrsize == 8:
            msg_w = i2c_msg.write(
                address, [reg])  # warning this is set up for 16-bit addresses
        elif addrsize == 16:
            msg_w = i2c_msg.write(
                address, [reg >> 8, reg & 0xff
                          ])  # warning this is set up for 16-bit addresses
        else:
            raise Exception("address must be 8 or 16 bits long only")
        msg_r = i2c_msg.read(address, length)
        self.i2c.i2c_rdwr(msg_w, msg_r)
        if ret_val == 0:
            for index in range(length):
                data_p[index] = ord(msg_r.buf[index])
        return ret_val

    def write8(self, addr, reg, data):
        if reg is None:
            d = int.from_bytes(data, 'big')
            self.i2c.write_byte(addr, d)
        else:
            r = int.from_bytes(reg, 'big')
            d = int.from_bytes(data, 'big')
            self.i2c.write_byte_data(addr, r, d)

    def read16(self, addr, reg):
        regInt = int.from_bytes(reg, 'big')
        return self.i2c.read_word_data(addr,
                                       regInt).to_bytes(2,
                                                        byteorder='little',
                                                        signed=False)
Пример #20
0
class PanTilt:
    """PanTilt HAT Driver

    Communicates with PanTilt HAT over i2c
    to control pan, tilt and light functions

    """
    REG_CONFIG = 0x00
    REG_SERVO1 = 0x01
    REG_SERVO2 = 0x03
    REG_WS2812 = 0x05
    REG_UPDATE = 0x4E
    UPDATE_WAIT = 0.03
    NUM_LEDS = 24

    def __init__(self,
                 enable_lights=True,
                 idle_timeout=2, # Idle timeout in seconds
                 light_mode=WS2812,
                 light_type=RGB,
                 servo1_min=575,
                 servo1_max=2325,
                 servo2_min=575,
                 servo2_max=2325,
                 address=0x15,
                 i2c_bus=None):

        self._is_setup = False

        self._idle_timeout = idle_timeout
        self._servo1_timeout = None
        self._servo2_timeout = None

        self._i2c_retries = 10
        self._i2c_retry_time = 0.01

        self._enable_servo1 = False
        self._enable_servo2 = False
        self._enable_lights = enable_lights
        self._light_on = 0

        self._servo_min = [servo1_min, servo2_min]
        self._servo_max = [servo1_max, servo2_max]

        self._light_mode = light_mode
        self._light_type = light_type

        self._i2c_address = address
        self._i2c = i2c_bus

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

        if self._i2c is None:
            try:
                from smbus2 import SMBus
                self._i2c = SMBus(1)
            except ImportError:
                if version_info[0] < 3:
                    raise ImportError("This library requires python-smbus\nInstall with: sudo apt-get install python-smbus")
                elif version_info[0] == 3:
                    raise ImportError("This library requires python3-smbus\nInstall with: sudo apt-get install python3-smbus")

        self.clear()
        self._set_config()
        atexit.register(self._atexit)

        self._is_setup = True

    def _atexit(self):
        if self._servo1_timeout is not None:
            self._servo1_timeout.cancel()

        if self._servo2_timeout is not None:
            self._servo2_timeout.cancel()

        self._enable_servo1 = False
        self._enable_servo2 = False

        self._set_config()

    def idle_timeout(self, value):
        """Set the idle timeout for the servos

        Configure the time, in seconds, after which the servos will be automatically disabled.

        :param value: Timeout in seconds

        """

        self._idle_timeout = value

    def _set_config(self):
        """Generate config value for PanTilt HAT and write to device."""

        config = 0
        config |= self._enable_servo1
        config |= self._enable_servo2 << 1
        config |= self._enable_lights << 2
        config |= self._light_mode    << 3
        config |= self._light_on      << 4

        self._i2c_write_byte(self.REG_CONFIG, config)

    def _check_int_range(self, value, value_min, value_max):
        """Check the type and bounds check an expected int value."""

        if type(value) is not int:
            raise TypeError("Value should be an integer")
        if value < value_min or value > value_max:
            raise ValueError("Value {value} should be between {min} and {max}".format(
                value=value,
                min=value_min,
                max=value_max))

    def _check_range(self, value, value_min, value_max):
        """Check the type and bounds check an expected int value."""

        if value < value_min or value > value_max:
            raise ValueError("Value {value} should be between {min} and {max}".format(
                value=value,
                min=value_min,
                max=value_max))

    def _servo_us_to_degrees(self, us, us_min, us_max):
        """Converts pulse time in microseconds to degrees

        :param us: Pulse time in microseconds
        :param us_min: Minimum possible pulse time in microseconds
        :param us_max: Maximum possible pulse time in microseconds

        """

        self._check_range(us, us_min, us_max)
        servo_range = us_max - us_min
        angle = (float(us - us_min) / float(servo_range)) * 180.0
        return int(round(angle, 0)) - 90

    def _servo_degrees_to_us(self, angle, us_min, us_max):
        """Converts degrees into a servo pulse time in microseconds

        :param angle: Angle in degrees from -90 to 90

        """

        self._check_range(angle, -90, 90)

        angle += 90
        servo_range = us_max - us_min
        us = (servo_range / 180.0) * angle
        return us_min + int(us)

    def _servo_range(self, servo_index):
        """Get the min and max range values for a servo"""

        return (self._servo_min[servo_index], self._servo_max[servo_index])

    def _i2c_write_block(self, reg, data):
        if type(data) is list:
            for x in range(self._i2c_retries):
                try:
                    self._i2c.write_i2c_block_data(self._i2c_address, reg, data)
                    return
                except IOError:
                    time.sleep(self._i2c_retry_time)
                    continue

            raise IOError("Failed to write block")
        else:
            raise ValueError("Value must be a list")

    def _i2c_write_word(self, reg, data):
        if type(data) is int:
            for x in range(self._i2c_retries):
                try:
                    self._i2c.write_word_data(self._i2c_address, reg, data)
                    return
                except IOError:
                    time.sleep(self._i2c_retry_time)
                    continue

            raise IOError("Failed to write word")

    def _i2c_write_byte(self, reg, data):
        if type(data) is int:
            for x in range(self._i2c_retries):
                try:
                    self._i2c.write_byte_data(self._i2c_address, reg, data)
                    return
                except IOError:
                    time.sleep(self._i2c_retry_time)
                    continue

            raise IOError("Failed to write byte")

    def _i2c_read_byte(self, reg):
        for x in range(self._i2c_retries):
            try:
                return self._i2c.read_byte_data(self._i2c_address, reg)
            except IOError:
                time.sleep(self._i2c_retry_time)
                continue

        raise IOError("Failed to read byte")

    def _i2c_read_word(self, reg):
        for x in range(self._i2c_retries):
            try:
                return self._i2c.read_word_data(self._i2c_address, reg)
            except IOError:
                time.sleep(self._i2c_retry_time)
                continue

        raise IOError("Failed to read byte")

    def clear(self):
        """Clear the buffer."""

        self._pixels = [0] * self.NUM_LEDS * 3
        self._pixels += [1]

    def light_mode(self, mode):
        """Set the light mode for attached lights.

        PanTiltHAT can drive either WS2812 or SK6812 pixels,
        or provide a PWM dimming signal for regular LEDs.

        * PWM - PWM-dimmable LEDs
        * WS2812 - 24 WS2812 or 18 SK6812 pixels

        """

        self.setup()

        self._light_mode = mode
        self._set_config()

    def light_type(self, set_type):
        """Set the light type for attached lights.

        Set the type of lighting strip connected:

        * RGB - WS2812 pixels with RGB pixel order
        * RGB - WS2812 pixels with GRB pixel order
        * RGBW - SK6812 pixels with RGBW pixel order
        * GRBW - SK6812 pixels with GRBW pixel order

        """

        self._light_type = set_type

    def num_pixels(self):
        """Returns the supported number of pixels depending on light mode.

        RGBW or GRBW support 18 pixels
        RGB supports 24 pixels

        """

        if self._light_type in [RGBW, GRBW]:
            return 18

        return 24

    def brightness(self, brightness):
        """Set the brightness of the connected LED ring.

        This only applies if light_mode has been set to PWM.

        It will be ignored otherwise.

        :param brightness: Brightness from 0 to 255

        """

        self.setup()

        self._check_int_range(brightness, 0, 255)

        if self._light_mode == PWM:
            # The brightness value is taken from the first register of the WS2812 chain
            self._i2c_write_byte(self.REG_WS2812, brightness)

    def set_all(self, red, green, blue, white=None):
        """Set all pixels in the buffer.

        :param red: Amount of red, from 0 to 255
        :param green: Amount of green, from 0 to 255
        :param blue: Amount of blue, from 0 to 255
        :param white: Optional amount of white for RGBW and GRBW strips

        """

        for index in range(self.num_pixels()):
            self.set_pixel(index, red, green, blue, white)

    def set_pixel_rgbw(self, index, red, green, blue, white):
        """Set a single pixel in the buffer for GRBW lighting stick

        :param index: Index of pixel from 0 to 17
        :param red: Amount of red, from 0 to 255
        :param green: Amount of green, from 0 to 255
        :param blue: Amount of blue, from 0 to 255
        :param white: Amount of white, from 0 to 255

        """

        self.set_pixel(index, red, green, blue, white)

    def set_pixel(self, index, red, green, blue, white=None):
        """Set a single pixel in the buffer.

        :param index: Index of pixel from 0 to 23
        :param red: Amount of red, from 0 to 255
        :param green: Amount of green, from 0 to 255
        :param blue: Amount of blue, from 0 to 255
        :param white: Optional amount of white for RGBW and GRBW strips

        """

        self._check_int_range(index, 0, self.num_pixels() - 1)

        for color in [red, green, blue]:
            self._check_int_range(color, 0, 255)

        if white is not None:
            self._check_int_range(white, 0, 255)

        if self._light_type in [RGBW, GRBW]:
            index *= 4
            if self._light_type == RGBW:
                self._pixels[index] = red
                self._pixels[index+1] = green
                self._pixels[index+2] = blue

            if self._light_type == GRBW:
                self._pixels[index] = green
                self._pixels[index+1] = red
                self._pixels[index+2] = blue

            if white is not None:
                self._pixels[index+3] = white

        else:
            index *= 3
            if self._light_type == RGB:
                self._pixels[index] = red
                self._pixels[index+1] = green
                self._pixels[index+2] = blue

            if self._light_type == GRB:
                self._pixels[index] = green
                self._pixels[index+1] = red
                self._pixels[index+2] = blue

    def show(self):
        """Display the buffer on the connected WS2812 strip."""

        self.setup()

        self._i2c_write_block(self.REG_WS2812, self._pixels[:32])
        self._i2c_write_block(self.REG_WS2812 + 32, self._pixels[32:64])
        self._i2c_write_block(self.REG_WS2812 + 64, self._pixels[64:])
        self._i2c_write_byte(self.REG_UPDATE, 1)

    def servo_enable(self, index, state):
        """Enable or disable a servo.

        Disabling a servo turns off the drive signal.

        It's good practise to do this if you don't want
        the Pan/Tilt to point in a certain direction and
        instead want to save power.

        :param index: Servo index: either 1 or 2
        :param state: Servo state: True = on, False = off

        """

        self.setup()

        if index not in [1, 2]:
            raise ValueError("Servo index must be 1 or 2")

        if state not in [True, False]:
            raise ValueError("State must be True/False")

        if index == 1:
            self._enable_servo1 = state
        else:
            self._enable_servo2 = state

        self._set_config()

    def servo_pulse_min(self, index, value):
        """Set the minimum high pulse for a servo in microseconds.

        :param value: Value in microseconds

        """

        if index not in [1, 2]:
            raise ValueError("Servo index must be 1 or 2")

        self._servo_min[index-1] = value

    def servo_pulse_max(self, index, value):
        """Set the maximum high pulse for a servo in microseconds.

        :param value: Value in microseconds

        """

        if index not in [1, 2]:
            raise ValueError("Servo index must be 1 or 2")

        self._servo_max[index-1] = value

    def get_servo_one(self):
        """Get position of servo 1 in degrees."""

        self.setup()

        us_min, us_max = self._servo_range(0)
        us = self._i2c_read_word(self.REG_SERVO1)

        try:
            return self._servo_us_to_degrees(us, us_min, us_max)
        except ValueError:
            return 0

    def get_servo_two(self):
        """Get position of servo 2 in degrees."""

        self.setup()

        us_min, us_max = self._servo_range(1)
        us = self._i2c_read_word(self.REG_SERVO2)
        try:
            return self._servo_us_to_degrees(us, us_min, us_max)
        except ValueError:
            return 0

    def servo_one(self, angle):
        """Set position of servo 1 in degrees.

        :param angle: Angle in degrees from -90 to 90

        """

        self.setup()

        if not self._enable_servo1:
            self._enable_servo1 = True
            self._set_config()

        us_min, us_max = self._servo_range(0)
        us = self._servo_degrees_to_us(angle, us_min, us_max)
        self._i2c_write_word(self.REG_SERVO1, us)

        if self._idle_timeout > 0:
            if self._servo1_timeout is not None:
                self._servo1_timeout.cancel()

            self._servo1_timeout = Timer(self._idle_timeout, self._servo1_stop)
            self._servo1_timeout.daemon = True
            self._servo1_timeout.start()

    def _servo1_stop(self):
        self._servo1_timeout = None
        self._enable_servo1 = False
        self._set_config()

    def servo_two(self, angle):
        """Set position of servo 2 in degrees.

        :param angle: Angle in degrees from -90 to 90

        """

        self.setup()

        if not self._enable_servo2:
            self._enable_servo2 = True
            self._set_config()

        us_min, us_max = self._servo_range(1)
        us = self._servo_degrees_to_us(angle, us_min, us_max)
        self._i2c_write_word(self.REG_SERVO2, us)

        if self._idle_timeout > 0:
            if self._servo2_timeout is not None:
                self._servo2_timeout.cancel()

            self._servo2_timeout = Timer(self._idle_timeout, self._servo2_stop)
            self._servo2_timeout.daemon = True
            self._servo2_timeout.start()

    def _servo2_stop(self):
        self._servo2_timeout = None
        self._enable_servo2 = False
        self._set_config()

    pan = servo_one
    tilt = servo_two
    get_pan = get_servo_one
    get_tilt = get_servo_two
Пример #21
0
class INA233:
    def __init__(self, bus, addr, max_i=15.0, r_shunt=0.002, debug=False):
        self.addr = addr
        self.max_i = max_i
        self.r_shunt = r_shunt
        self.debug = debug
        self.energy_acc = 0
        self.last = datetime.utcnow()
        self.bus = SMBus(bus)
        self.init()

    # Set the INA233 to default settings
    def set_defaults(self):
        self.bus.write_byte(self.addr, 0x12)
        self.energy_acc = 0
        self.last = datetime.utcnow()

    # Initialise the INA233 for I and P readings
    def init(self):
        # Reset device to defaults
        self.set_defaults()

        # Debug
        if self.debug:
            print(
                "INA233 0x%02X Init with max_i: %.1f Amps, r_shunt: %.5f ohms"
                % (self.addr, self.max_i, self.r_shunt))

        # Current LSB is stored as float so we do not need to compute m later
        self.current_lsb = float(self.max_i) / 2**15
        cal = 0.00512 / (self.current_lsb * self.r_shunt)

        # Round to nearest int for programming
        cal_r = int(round(cal))

        # Debug
        if self.debug:
            print(
                "INA233 0x%02X MFR_CALIBRATION Rounded from %.4f to %d (0x%04X)"
                % (self.addr, cal, cal_r, cal_r))
            print("INA233 0x%02X current_lsb: %.15f" %
                  (self.addr, self.current_lsb))

        # Set calibration registers in device
        self.set_mfr_calibration(cal_r)
        self.set_mfr_device_config(read_ein=1)
        self.set_mfr_adc_config(avg=5, vbusct=5, vshct=4, mode=7)

    # Set the MFR_CALIBRATION register
    def set_mfr_calibration(self, cal):
        # Build config value
        cali = (cal & 0x7FFF)

        #Write to register
        self.bus.write_word_data(self.addr, 0xD4, cali)
        mfr_calibration = self.bus.read_word_data(self.addr, 0xD4)

        # Debug
        if self.debug:
            if (mfr_calibration != cali):
                print(
                    "INA233 0x%02X MFR_CALIBRATION readback error, write: 0x%04X, read: 0x%04X"
                    % (self.addr, cali, mfr_calibration))
            else:
                print(
                    "INA233 0x%02X MFR_CALIBRATION readback OK, read: 0x%04X" %
                    (self.addr, mfr_calibration))

    # Set MFR_ADC_CONFIG register
    def set_mfr_adc_config(self, avg=0, vbusct=4, vshct=4, mode=7):
        # Build config value
        adc_conf = ((0x4 & 0xF) << 12)
        adc_conf += ((avg & 0x7) << 9)
        adc_conf += ((vbusct & 0x7) << 6)
        adc_conf += ((vshct & 0x7) << 3)
        adc_conf += ((mode & 0x7) << 0)

        # Write to register
        self.bus.write_word_data(self.addr, 0xD0, adc_conf)
        adc_config = self.bus.read_word_data(self.addr, 0xD0)

        # Debug
        if self.debug:
            if (adc_config != adc_conf):
                print(
                    "INA233 0x%02X MFR_ADC_CONFIG readback error, write: 0x%04X, read: 0x%04X"
                    % (self.addr, adc_conf, adc_config))
            else:
                print(
                    "INA233 0x%02X MFR_ADC_CONFIG readback OK, read: 0x%04X" %
                    (self.addr, adc_config))

    #Set MFR_DEVICE_CONFIG register
    def set_mfr_device_config(self,
                              ein_status=0,
                              ein_accum=0,
                              i2c_filt=0,
                              read_ein=0,
                              alert=1,
                              apol=0):
        # Build config value
        dev_conf = ((ein_status & 0x01) << 7)
        dev_conf += ((ein_accum & 0x03) << 4)
        dev_conf += ((i2c_filt & 0x01) << 3)
        dev_conf += ((read_ein & 0x01) << 2)
        dev_conf += ((alert & 0x01) << 1)
        dev_conf += ((apol & 0x01) << 0)

        # Write to register
        self.bus.write_byte_data(self.addr, 0xD5, dev_conf)
        device_config = self.bus.read_byte_data(self.addr, 0xD5)

        # Debug
        if self.debug:
            if (device_config != dev_conf):
                print(
                    "INA233 0x%02X MFR_DEVICE_CONFIG readback error, write: 0x%02X, read: 0x%02X"
                    % (self.addr, dev_conf, device_config))
            else:
                print(
                    "INA233 0x%02X MFR_DEVICE_CONFIG readback OK, read: 0x%02X"
                    % (self.addr, device_config))

    # Obtain voltage reading
    def v_read(self):
        vin_read = float(self.bus.read_word_data(self.addr, 0x88))
        vin = (1.0 / 8) * (vin_read * 10**-2)

        # Debug
        if self.debug:
            print("INA233 0x%02X Voltage : %.2fV" % (self.addr, vin))

        return vin

    # Obtain current reading
    def i_read(self):
        iin_read = self.bus.read_word_data(self.addr, 0x89)

        # Check sign
        if (iin_read & 0x8000):
            iin_read = iin_read - 0x10000
        iin = self.current_lsb * iin_read

        # Debug
        if self.debug:
            print("INA233 0x%02X Current : %.2fA" % (self.addr, iin))

        return iin

    # Obtain power reading
    def p_read(self):
        pin_read = float(self.bus.read_word_data(self.addr, 0x97))
        pin = self.current_lsb * 25 * pin_read

        # Debug
        if self.debug:
            print("INA233 0x%02X Power   : %.2fW" % (self.addr, pin))

        return pin

    # Read total energy (kWh) since last reset
    def e_read(self):
        # Read energy register
        ein_read = self.bus.read_i2c_block_data(self.addr, 0x86, 7)
        # Get time of this read
        t = datetime.utcnow()

        # Extract sub-values
        pow_acc = (ein_read[1] & 0xFF) + ((ein_read[2] & 0xFF) << 8)
        pow_acc_roll = ein_read[3] & 0xFF
        samples = (ein_read[4] & 0xFF) + ((ein_read[5] & 0xFF) << 8) + (
            (ein_read[6] & 0xFF) << 16)

        # Total energy for this sample period (since self.last)
        # Assumes autoclear enabled in MFR_DEVICE_CONFIG
        # Assumes this command is run frequently enough to avoid roll overs (via reset on read)
        total_e = self.current_lsb * 25 * ((pow_acc_roll * 0xFFFF) + pow_acc)

        # Energy is total power accumulated * time since measurement start
        if (samples != 0):
            dur = (t - self.last).total_seconds()
            self.last = t
            self.energy_acc += (
                (float(total_e) / samples) * dur) / (3600 * 1000)

            #Debug
            if self.debug:
                print("INA233 0x%02X Energy  : %.8fkWh" %
                      (self.addr, self.energy_acc))

            return self.energy_acc
        else:
            return 0.0

    # Print debug information for this INA233 device
    def print_debug(self):
        print("\nDebug information for INA233 addr: 0x%02X" % self.addr)
        # Get MFR_MODEL
        mfr_model = self.bus.read_i2c_block_data(self.addr, 0x9A, 7)
        print("MFR_MODEL   : " + bytearray(mfr_model).decode('utf-8'))
        # Get MFR_ID
        mfr_id = self.bus.read_i2c_block_data(self.addr, 0x99, 3)
        print("MFR_ID      : " + bytearray(mfr_id).decode('utf-8'))
        # Get MFR_MODEL
        mfr_revision = self.bus.read_word_data(self.addr, 0x9B)
        print("MFR_REVISION: 0x%04X" % mfr_revision)
        # Get MFR_CALIBRATION
        mfr_calibration = self.bus.read_word_data(self.addr, 0xD4)
        print("MFR_CALIC   : 0x%04X" % mfr_calibration)
        # Get MFR_DEVICE_CONDIG
        mfr_dev_config = self.bus.read_byte_data(self.addr, 0xD5)
        print("MFR_DEV_CONF: 0x%02X" % mfr_dev_config)

        # Capability
        capability = self.bus.read_byte_data(self.addr, 0x19)
        print("Capability  : 0x%02X" % capability)
        # Status byte
        status_byte = self.bus.read_byte_data(self.addr, 0x78)
        print("Status byte : 0x%02X" % status_byte)
        # Status word
        status_word = self.bus.read_word_data(self.addr, 0x79)
        print("Status word : 0x%04X" % status_word)
        # Status iout
        status_iout = self.bus.read_byte_data(self.addr, 0x7B)
        print("Status IOUT : 0x%02X" % status_iout)
        # Status input
        status_input = self.bus.read_byte_data(self.addr, 0x7C)
        print("Status INPUT: 0x%02X" % status_input)
        # Status communications
        status_cml = self.bus.read_byte_data(self.addr, 0x7E)
        print("Status CML  : 0x%02X" % status_cml)
        # Status MFR Specific
        status_mfr = self.bus.read_byte_data(self.addr, 0x80)
        print("Status MFR  : 0x%02X" % status_mfr)
        # ADC_CONFIG
        adc_config = self.bus.read_word_data(self.addr, 0xD0)
        print("ADC_CONFIG  : 0x%04X" % adc_config)

        print("\n")
Пример #22
0
registers = {
    'CONFIG': 0x01,
    'TUPPER': 0x02,
    'TLOWERL': 0x03,
    'TCRIT': 0x04,
    'TA': 0x05,
    'MANUFACTURER_ID': 0x06,
    'DEVICE_ID': 0x07,
    'RESOLUTION': 0x08,
}

bus = SMBus(1)
address = 0x18

for k in registers:
    dat = bus.read_word_data(0x18, registers[k])
    print('{} -> {}'.format(k, dat))
    
# Parse temp
v = bus.read_word_data(0x18, 0x05)
print('Raw: {}'.format(v))
# Split in 2-complements
ub=v & 0xFF
lb=(v >> 8) & 0xFF
# Clear flags / take lower 13
ub = ub & 0x1F
print('1: {}, 2: {}'.format(ub, lb))
# Check for negative values
if (ub & 0x10) == 0x10:
    ub = ub & 0x0F
    t = 256 - (ub * 16 + lb/16)
Пример #23
0
class Sfp():
    def __init__(self):
        """Init smbus channel and SFP driver on specified address."""

        self.data = {
            "module_info": {
                "manufacturer": None,
                "revision": None,
                "serial_num": None,
                "sfp_type": None,
                "connector": None,
                "bitrate": None,
                "wavelength": None
            },
            "diagnostics": {
                "temp": None,
                "tx_power_dBm": None,
                "rx_power_dBm": None,
                "tx_power": None,
                "rx_power": None
            }
        }

        try:
            self.i2c_bus = SMBus(I2C_CHANNEL)
            self.init()
        except Exception as e:
            log.error("An error occured during sfp initializion!")
            self.i2c_bus = None
            raise Exception(e)
   
    def __del__(self):
        """Driver destructor."""
        self.i2c_bus = None

    def init(self):
        """Init and read all info registers"""
        try:
            manufacturer = self.i2c_bus.read_i2c_block_data(SFP_I2C_INFO_ADDRESS, SFP_MANUFACTURER_REG, SFP_MANUFACTURER_LENGTH)
            self.data["module_info"]["manufacturer"] = "".join(chr(x) for x in manufacturer)
        except Exception as e:
            raise Exception(f"An error occured during manufacturer data i2c read: {e}")

        try:    
            revision = self.i2c_bus.read_i2c_block_data(SFP_I2C_INFO_ADDRESS, SFP_REVISION_REG, SFP_REVISION_LENGTH)
            self.data["module_info"]["revision"] = "".join(chr(x) for x in revision)
        except Exception as e:
            raise Exception(f"An error occured during revision i2c read: {e}")

        try:    
            serial_num = self.i2c_bus.read_i2c_block_data(SFP_I2C_INFO_ADDRESS, SFP_SERIAL_NO_REG, SFP_SERIAL_NO_LENGTH)
            self.data["module_info"]["serial_num"] = "".join(chr(x) for x in serial_num)
        except Exception as e:
            raise Exception(f"An error occured during serial number i2c read: {e}")

        try:    
            self.data["module_info"]["sfp_type"] = self.i2c_bus.read_byte_data(SFP_I2C_INFO_ADDRESS, SFP_TYPE_REG)
        except Exception as e:
            raise Exception(f"An error occured during sfp type i2c read: {e}")
        
        try:
            self.data["module_info"]["connector"] = self.i2c_bus.read_byte_data(SFP_I2C_INFO_ADDRESS, SFP_CONNECTOR_REG)
        except Exception as e:
            raise Exception(f"An error occured during connector type i2c read: {e}")

        try:    
            self.data["module_info"]["bitrate"] = self.i2c_bus.read_byte_data(SFP_I2C_INFO_ADDRESS, SFP_BITRATE_REG) * 100
        except Exception as e:
            raise Exception(f"An error occured during bitrate i2c read: {e}")

        try:    
            wavelength = self.i2c_bus.read_word_data(SFP_I2C_INFO_ADDRESS, SFP_WAVELENGTH_REG)
            self.data["module_info"]["wavelength"] = (wavelength & 0xff) * 256 + ((wavelength & 0xff00) >> 8)
        except Exception as e:
            raise Exception(f"An error occured during wavelength i2c read: {e}")

        try:    
            self.diag_settings = self.i2c_bus.read_byte_data(SFP_I2C_INFO_ADDRESS, SFP_DIAG_MONITORING_REG)
        except Exception as e:
            raise Exception(f"An error occured during diagnostics settings i2c read: {e}")

    def convert_to_fp(self, number, num_bits, divisor):
        """Convert num_bits bit number to a floating point number"""
        val = 0
        for bit in range(0, num_bits):
            val += (number & (1 << bit)) / divisor
        return val

    def convert_to_dB(self, mW):
        """Convert mW to dB and return value"""
        if mW == 0.0:
            return -40.0  # -40.0 is lower limit
        return 10 * np.log10(mW)

    def get_diagnostics(self):
        """Get sfp module diagnostics"""

        diagnostics_block = self.i2c_bus.read_i2c_block_data(SFP_I2C_DIAG_ADDRESS, SFP_DIAG_REG_START, DIAG_DATA_LENGTH)
        temp_bytes = diagnostics_block[TEMP_OFFSET: VCC_OFFSET]
        temp_h = float(np.int8(temp_bytes[0]))  # signed int8
        temp_l = self.convert_to_fp(temp_bytes[1], 8, 256)
        temp = temp_h + temp_l
        self.data["diagnostics"]["temp"] = temp

        # next is transciever supply voltage - skip this for now

        # next is tx bias current in uA - skip

        # next is tx output power in mW
        tx_bytes = diagnostics_block[TX_POWER_OFFSET:RX_POWER_OFFSET]
        tx_power = float(np.uint16((tx_bytes[0] << 8) | tx_bytes[1]) / 10000)  # LSB is equal to 100 uW, so the range is [0, 6.5535]mW
        self.data["diagnostics"]["tx_power"] = tx_power
        tx_power_dbm = round(self.convert_to_dB(tx_power), 3)
        self.data["diagnostics"]["tx_power_dBm"] = float(tx_power_dbm)

        # next is rx received power in mW
        rx_bytes = diagnostics_block[RX_POWER_OFFSET:]
        rx_power = float(np.uint16((rx_bytes[0] << 8) | rx_bytes[1]) / 10000) # LSB is equal to 100 uW, so the range is [0, 6.5535]mW
        self.data["diagnostics"]["rx_power"] = rx_power
        rx_power_dbm = round(self.convert_to_dB(rx_power), 3)
        self.data["diagnostics"]["rx_power_dBm"] = float(rx_power_dbm)

        return self.data["diagnostics"]

    def get_module_info(self):
        """Get data"""
        return self.data["module_info"]
Пример #24
0
class BMSCom:

    def __init__(self):
        self._bus = SMBus(1)  # indicates /dev/ic2-1
        self.address = 0x0B  # bus address of the battery status manager
        self.polynomial = '100000111'  # PEC checksum polynomial binary 0x107 (CRC-8)
        self._bus.pec = 1  # Enable PEC verification
        # commands read
        self.reg_cell_voltage = 0x09  # command code to read the voltage of a cell (1mV)
        self.reg_rsoc100 = 0x0D  # command code to read the RSOC value based on a 0−100 scale (1%)
        self.reg_rsoc1000 = 0x0F  # command code to read the RSOC value based on a 0−1000 scale (0.1%)
        # commands write
        self.reg_low_rsoc = 0x13  # command code to sets or read the RSOC threshold to generate Alarm signal (1%)
        self.reg_low_voltage = 0x14  # command code to sets or read the voltage threshold to generate Alarm signal (1mV)

    # gets voltage for a cell in mV
    # return int
    def get_voltage(self):
        return self._bus.read_word_data(i2c_addr=self.address, register=self.reg_cell_voltage)

    # gets battery charge in % with a 1% precision
    # return int
    def get_charge100(self):
        return self._bus.read_word_data(i2c_addr=self.address, register=self.reg_rsoc100)

    # gets battery charge in % with a 0.1% precision
    # return int
    def get_charge1000(self):
        return self._bus.read_word_data(i2c_addr=self.address, register=self.reg_rsoc1000) / 10

    # separate a number in two Bytes (data Byte low and data_byte_high)
    # input int <= 0xFFFF = 65535
    # return a list [data_byte_low, data_byte_high]
    @staticmethod
    def _separate_bytes(number):
        list_bytes = [255, 255]
        if number <= 0xFFFF & number >= 0:
            data_byte_high1 = number // (16 ** 3)  # most significant 4 bits of the most significant Byte
            data_byte_high2 = (number - data_byte_high1 * 16 ** 3) // (16 ** 2)  # less significant 4 bits of the most
            # significant Byte
            data_byte_high = data_byte_high1 * 16 + data_byte_high2  # most significant Byte
            data_byte_low1 = (number - data_byte_high1 * 16 ** 3 - data_byte_high2 * 16 ** 2) // (16 ** 1)  # most
            # significant 4 bits of the less significant Byte
            data_byte_low2 = (
                        number - data_byte_high1 * 16 ** 3 - data_byte_high2 * 16 ** 2 - data_byte_low1 * 16)  # less
            # significant 4 bits of the less significant Byte
            data_byte_low = data_byte_low1 * 16 + data_byte_low2  # less significant Byte
            list_bytes = [data_byte_low, data_byte_high]
        elif number < 0:
            list_bytes = [0, 0]
        return list_bytes

    # xor operation with str
    @staticmethod
    def _xor(first, second):

        # initialize result
        result = []

        # Traverse all bits, if bits are
        # same, then XOR is 0, else 1
        for i in range(1, len(second)):
            if first[i] == second[i]:
                result.append('0')
            else:
                result.append('1')

        return ''.join(result)

    # Performs Modulo-2 division
    def _mod2div(self, divident, divisor):

        # Number of bits to be XORed at a time.
        pick = len(divisor)

        # Slicing the divident to appropriate
        # length for particular step
        tmp = divident[0: pick]

        while pick < len(divident):

            if tmp[0] == '1':

                # replace the divident by the result
                # of XOR and pull 1 bit down
                tmp = self._xor(divisor, tmp) + divident[pick]

            else:  # If leftmost bit is '0'

                # If the leftmost bit of the dividend (or the
                # part used in each step) is 0, the step cannot
                # use the regular divisor; we need to use an
                # all-0s divisor.
                tmp = self._xor('0' * pick, tmp) + divident[pick]

                # increment pick to move further
            pick += 1

        # For the last n bits, we have to carry it out
        # normally as increased value of pick will cause
        # Index Out of Bounds.
        if tmp[0] == '1':
            tmp = self._xor(divisor, tmp)
        else:
            tmp = self._xor('0' * pick, tmp)

        checkword = tmp
        return checkword

        # Function used at the sender side to encode

    # calcul checksum CRC-8 for self.polynomial
    # inputs int
    # output int
    def _calculation_checksum(self, register, data_byte_low, data_byte_high):
        write_adress = self.address * 2  # address for writing
        data_send = bin(write_adress * 2 ** 24 + register * 2 ** 16 + data_byte_low * 2 ** 8 + data_byte_high)  #
        # transform data in srt binary
        data_send = data_send[2:len(data_send)]  # get rid of the beginning ('0b')
        l_polynomial = len(self.polynomial)

        # Appends n-1 zeroes at end of data
        appended_data = data_send + '0' * (l_polynomial - 1)
        str_checksum = self._mod2div(appended_data, self.polynomial)
        n = len(str_checksum)
        checksum = 0
        for i in range(0, len(str_checksum)):
            n = n - 1
            if str_checksum[i] == '1':
                bit = 1
            else:
                bit = 0
            checksum = checksum + bit * 2 ** n
        return checksum

    # set low voltage for the alarm in mV
    # input int <= 0xFFFF = 65535
    def set_low_voltage_alarm(self, min_voltage):
        [data_byte_low, data_byte_high] = self._separate_bytes(min_voltage)
        checksum = self._calculation_checksum(self.reg_low_voltage, data_byte_low, data_byte_high)
        self._bus.write_i2c_block_data(i2c_addr=self.address, register=self.reg_low_voltage,
                                       data=[data_byte_low, data_byte_high, checksum])

    # set low rsoc for the alarm in %
    # input int <= 0x0064 = 100
    def set_low_rsoc_alarm(self, min_rsoc):
        if min_rsoc > 100:
            min_rsoc = 100
        [data_byte_low, data_byte_high] = self._separate_bytes(min_rsoc)
        checksum = self._calculation_checksum(self.reg_low_rsoc, data_byte_low, data_byte_high)
        self._bus.write_i2c_block_data(i2c_addr=self.address, register=self.reg_low_rsoc,
                                       data=[data_byte_low, data_byte_high, checksum])
Пример #25
0
def printHex(data):
    hexChar = ''
    for val in data:
        hexChar += format('0x%02x ' % val)


commObj = SMBus(2)
if commObj == None:
    print('Not able to open driver')
    quit()

curList = list()
avecurList = list()
cur = c_short()
for i in range(100):
    cur = commObj.read_word_data(tgtAddress, SBSCurrent)
    avecurr = commObj.read_word_data(tgtAddress, SBSAveCurrent)
    current = c_short(cur).value
    aveCurrent = c_short(avecurr).value
    curList.append(current)
    avecurList.append(aveCurrent)
    print('Current: ', current, 'Average Current', aveCurrent)
    time.sleep(1.0)

mincur = min(curList)
maxcur = max(curList)
print('Lowest current: %d Highest Current %d' % (mincur, maxcur))

minaveCurr = min(avecurList)
maxaveCurr = max(avecurList)
print('Lowest Ave current: %d Highest Ave Current %d' %
Пример #26
0
class InputModule(AbstractInput):
    """
    A sensor support class that measures the Chirp's moisture, temperature
    and light

    """

    def __init__(self, input_dev, testing=False):
        super(InputModule, self).__init__(input_dev, testing=testing, name=__name__)

        if not testing:
            self.i2c_address = int(str(input_dev.i2c_location), 16)
            self.i2c_bus = input_dev.i2c_bus
            self.bus = SMBus(self.i2c_bus)
            self.filter_average('lux', init_max=3)

    def get_measurement(self):
        """ Gets the light, moisture, and temperature """
        self.return_dict = measurements_dict.copy()

        if self.is_enabled(0):
            self.value_set(0, self.filter_average('lux', measurement=self.light()))

        if self.is_enabled(1):
            self.value_set(1, self.moist())

        if self.is_enabled(2):
            self.value_set(2, self.temp() / 10.0)

        return self.return_dict

    def get_reg(self, reg):
        # read 2 bytes from register
        val = self.bus.read_word_data(self.i2c_address, reg)
        # return swapped bytes (they come in wrong order)
        return (val >> 8) + ((val & 0xFF) << 8)

    def reset(self):
        # To reset the sensor, write 6 to the device I2C address
        self.bus.write_byte(self.i2c_address, 6)

    def set_addr(self, new_addr):
        # To change the I2C address of the sensor, write a new address
        # (one byte [1..127]) to register 1; the new address will take effect after reset
        self.bus.write_byte_data(self.i2c_address, 1, new_addr)
        self.reset()
        # self.address = new_addr

    def moist(self):
        # To read soil moisture, read 2 bytes from register 0
        return self.get_reg(0)

    def temp(self):
        # To read temperature, read 2 bytes from register 5
        return self.get_reg(5)

    def light(self):
        # To read light level, start measurement by writing 3 to the
        # device I2C address, wait for 3 seconds, read 2 bytes from register 4
        self.bus.write_byte(self.i2c_address, 3)
        time.sleep(1.5)
        lux = self.get_reg(4)
        if lux == 0:
            return 65535.0
        else:
            return(1 - (lux / 65535.0)) * 65535.0
Пример #27
0
"""
@author: root
"""

import time
from smbus2 import SMBus 

tgtAddress = 0x0B
voltcmd = 0x09

def printHex(data):
    hexChar = ''
    for val in data:
        hexChar += format('0x%02x ' % val) 

commObj = SMBus(2)
if commObj == None:
    print('Not able to open driver')
    quit()


for i in range(200): 
    b = commObj.read_word_data(tgtAddress, voltcmd)
    #print('Byte Word: ', b)

    commObj.write_i2c_block_data(tgtAddress, 0x44, [2,0])
    verString = commObj.read_i2c_block_data(tgtAddress, 0x44, 13)
    print('Result ', verString)

commObj.close()