Beispiel #1
7
class Device(object):
    def __init__(self, address, bus):
        self._bus = SMBus(bus)
        self._address = address

    def writeRaw8(self, value):
        value = value & 0xff
        self._bus.write_byte(self._address, value)

    def readRaw8(self):
        result = self._bus.read_byte(self._address) & 0xff
        return result

    def write8(self, register, value):
        value = value & 0xff
        self._bus.write_byte_data(self._address, register, value)

    def readU8(self, register):
        result = self._bus.read_byte_data(self._address, register) & 0xFF
        return result

    def readS8(self, register):
        result = self.readU8(register)
        if result > 127:
            result -= 256
        return result

    def write16(self, register, value):
        value = value & 0xffff
        self._bus.write_word_data(self._address, register, value)

    def readU16(self, register, little_endian = True):
        result = self._bus.read_word_data(self._address,register) & 0xFFFF
        if not little_endian:
            result = ((result << 8) & 0xFF00) + (result >> 8)
        return result

    def readS16(self, register, little_endian = True):
        result = self.readU16(register, little_endian)
        if result > 32767:
            result -= 65536
        return result

    def writeList(self, register, data):
        self._bus.write_i2c_block_data(self._address, register, data)

    def readList(self, register, length):
        results = self._bus.read_i2c_block_data(self._address, register, length)
        return results
class veml6075:
    def __init__(self, addr=0x10):
        self.i2c = SMBus(1)
        self.addr = addr
        self.i2c.write_byte_data(self.addr, 0x00, (0 & 7) << 4)
        self.a = 2.22
        self.c = 2.95
        self.b = 1.33
        self.d = 1.74
        self.UVAresp = 0.001461
        self.UVBresp = 0.002591
        self.UVA2Wm = 1 / 93
        self.UVB2Wm = 1 / 210

    def read(self):
        UVA = self.i2c.read_word_data(self.addr, 0x07)
        UVB = self.i2c.read_word_data(self.addr, 0x09)
        UVcomp1 = self.i2c.read_word_data(self.addr, 0x0A)
        UVcomp2 = self.i2c.read_word_data(self.addr, 0x0B)
        UVAcalc = UVA - (self.a * UVcomp1) - (self.b * UVcomp2)
        UVBcalc = UVB - (self.c * UVcomp1) - (self.d * UVcomp2)
        UVAI = UVAcalc * self.UVAresp
        UVBI = UVBcalc * self.UVBresp
        UVI = (UVAI + UVBI) / 2
        UVAWm = UVAcalc * self.UVA2Wm
        UVBWm = UVBcalc * self.UVB2Wm
        return UVI
Beispiel #3
0
class RHTS:
    """ Driver for Si7021 temperatuer and humidity sensor
    """
    meas_RH = 0xf5
    read_temp = 0xe0
    reset = 0xfe
    def __init__(self, i2cbus, addr):
        self.i2cbus = i2cbus
        self.bus = SMBus(self.i2cbus)
        self.addr = addr
    def measure(self):
        self.bus.write_byte(self.addr, self.meas_RH)
        sleep(0.3)
    def readall(self):
        """Units of temperature in  deg C """
        self.measure()
        # Pull the MSB of the RH data
        data0 = self.bus.read_byte(self.addr)
        # Pull the LSB from the RH data
        data1 = self.bus.read_byte(self.addr)
        # Calculate the RH from user manual section 5.1.1
        RH = ((data0*256 + data1)*125 / 65535.0)-6
        self.RH = max(0, min(100, RH)) 
        # Pull the two byte temperature dats - needs byte shifting
        data3 = self.bus.read_word_data(self.addr, self.read_temp)
        # Shift the bytes
        data4 = ((data3 & 0xff) << 8) | (data3 >> 8)
        # Calculate the temperature in deg C from manual section 5.1.1
        self.tempC = 175.72 * data4 / 65536. - 46.85
        # return the RH and Temperature data
        return [self.tempC, self.RH]
Beispiel #4
0
class TemperatureSensor():
    """
    Read temperature using NXT Temperature sensor
    """
    def __init__(self):

        # Set LEGO port for NXT Temp sensor
        lego_port = LegoPort(INPUT_2)
        lego_port.mode = 'other-i2c'
        sleep(0.5)
        # Settings for I2C (SMBus(4) for INPUT_2)
        self.lego_bus = SMBus(4)
        # LM75 address
        self.address = NXT_SENSOR_ADDRESS

    def read_temperature_c(self):
        raw = self.lego_bus.read_word_data(self.address, 0) & 0xFFFF
        raw = ((raw << 8) & 0xFF00) + (raw >> 8)
        temp = (raw / 32.0) / 8.0
        return temp

    def to_fahrenheit(self, temp):
        temp = (temp * (9.0 / 5.0)) + 32.0
        return temp

    def read_temperature_f(self):
        temp = self.to_fahrenheit(self.read_temperature_c())
        return temp
def get_temp():
    # zlecenie konwersji
    i2c_bus = SMBus(1)
    i2c_bus.write_byte_data(Register.LIGHT2_ADDRESS, 10, 1)
    sleep(1)
    cel = i2c_bus.read_word_data(0x20, 5)
    cel = cel >> 8
    return cel
Beispiel #6
0
def get_temp():
    # zlecenie konwersji
    i2c_bus = SMBus(1)
    i2c_bus.write_byte_data(Register.LIGHT2_ADDRESS, 10, 1)
    sleep(1)
    cel = i2c_bus.read_word_data(0x20, 5)
    cel = cel >> 8
    return cel
Beispiel #7
0
def range_dist():

    sonar = False
    lidar_sens = False  # lidar sensing True, else EZ4 sonar or VL53L1X

    if sonar:
        # does not work well on grass
        from smbus import SMBus
        ##        i2cbus = SMBus(1)
        while True:
            try:
                i2cbus = SMBus(1)
                i2cbus.write_byte(0x70, 0x51)
                time.sleep(0.12)
                val = i2cbus.read_word_data(0x70, 0xE1)
                distance_in_cm = val >> 8 | (val & 0x0F) << 8
                ##                print distance_in_cm, 'cm'
                print(distance_in_cm, 'cm', file=f)
                msg_sensor(distance_in_cm, 25, 400),  #sonar facing down

            except IOError as err:
                print(err)

            time.sleep(0.1)

    if lidar_sens:
        from lidar_lite import Lidar_Lite
        lidar = Lidar_Lite()
        connected = lidar.connect(1)
        if connected < 0:
            print("\nlidar not connected")
        else:
            print("\nlidar connected")
        while True:
            dist = lidar.getDistance()
            print(dist, 'cm')
            print(dist, 'cm', file=f)
            msg_sensor(dist, 25, 700),  #lidar facing down
            time.sleep(0.2)

    else:
        # does not work in sunlight
        import VL53L1X
        tof = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x29)
        tof.open()  # Initialise the i2c bus and configure the sensor
        tof.start_ranging(
            2
        )  # Start ranging, 1 = Short Range, 2 = Medium Range, 3 = Long Range
        # Short range max:1.3m, Medium range max:3m, Long range max:4m
        while True:
            distance_in_cm = tof.get_distance(
            ) / 10  # Grab the range in cm (mm)
            time.sleep(0.2)  # timeout mavlink rangefinder = 500 ms
            print(distance_in_cm, 'cm', file=f)
            msg_sensor(distance_in_cm, 25, 250),  #sensor facing down

        tof.stop_ranging()  # Stop ranging
Beispiel #8
0
 def getPowerOut(self, fromDRQ):
     if (fromDRQ == True):
         bus = SMBus(1)
         self.powerOut = self.decodePMBus(
             bus.read_word_data(self.address, 0x96))
         bus.close()
     else:
         self.powerOut = self.voltageOut * self.current
     return self.powerOut
Beispiel #9
0
class MTSMBus(I2CBus):
    """ Multi-thread compatible SMBus bus.

    This is just a wrapper of SMBus, serializing I/O on the bus for use
    in multi-threaded context and adding _i2c_ variants of block transfers.
    """

    def __init__(self, bus_id=1, **kwargs):
        """
        :param int bus_id: the SMBus id (see Raspberry Pi documentation)
        :param kwargs: parameters transmitted to :py:class:`smbus.SMBus` initializer
        """
        I2CBus.__init__(self, **kwargs)
        self._bus = SMBus(bus_id)
        # I/O serialization lock
        self._lock = threading.Lock()

    def read_byte(self, addr):
        with self._lock:
            return self._bus.read_byte(addr)

    def write_byte(self, addr, data):
        with self._lock:
            self._bus.write_byte(addr, data)

    def read_byte_data(self, addr, reg):
        with self._lock:
            return self._bus.read_byte_data(addr, reg)

    def write_byte_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_byte_data(addr, reg, data)

    def read_word_data(self, addr, reg):
        with self._lock:
            return self._bus.read_word_data(addr, reg)

    def write_word_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_word_data(addr, reg, data)

    def read_block_data(self, addr, reg):
        with self._lock:
            return self._bus.read_block_data(addr, reg)

    def write_block_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_block_data(addr, reg, data)

    def read_i2c_block_data(self, addr, reg, count):
        with self._lock:
            return self._bus.read_i2c_block_data(addr, reg, count)

    def write_i2c_block_data(self, addr, reg, data):
        with self._lock:
            self._bus.write_i2c_block_data(addr, reg, data)
Beispiel #10
0
class LocalhostSMBusSlave(SMBusSlave):
    def __init__(self, bus, address):
        SMBusSlave.__init__(self, bus, address)
        self.bus = SMBus(bus)
        self.address = address

    #return: one byte hex string without '0x': '12'
    def get_byte(self, offset):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_byte_data(self.address, offset)
        time.sleep(self.interval)
        data = hex(ret)
        return data[2:].zfill(2)

    #input: offset:str, data:int
    def set_byte(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        self.bus.write_byte_data(self.address, offset, data)
        time.sleep(self.interval)

    #return: two byte hex string without '0x': '1234'
    def get_word(self, offset):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_word_data(self.address, offset)
        data = hex(ret)
        time.sleep(self.interval)
        return data[2:].zfill(4)

    def set_word(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        if sys.byteorder == "big":
            data = ((data & 0xff00) >> 8) + ((data & 0x00ff) << 8)
        self.bus.write_word_data(self.address, offset, data)
        time.sleep(self.interval)

    #return: hex string list per byte,without '0x' :['12', '0a']
    def get_block(self, offset, length="32"):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        ret = self.bus.read_block_data(self.address, offset)
        time.sleep(self.interval)
        hex_ret = [hex(i)[2:].zfill(2) for i in ret]
        return hex_ret

    def set_block(self, offset, data):
        #        print "%s %s" % (datetime.datetime.utcnow().strftime("%H:%M:%S.%f")[:-4], sys._getframe().f_code.co_name)
        data_arr = [(data & 0x00ff), ((data & 0xff00) >> 8)]
        #self.bus.write_i2c_block_data(self.address, offset, data_arr)
        self.bus.write_block_data(self.address, offset, data_arr)
        time.sleep(self.interval)
Beispiel #11
0
class PapirusTemperature:
    def __init__(self, i2c_bus=1):
        self.bus = SMBus(i2c_bus)

    def __read_raw(self):
        n = self.bus.read_word_data(0x48, 0x00)
        r = ((((n << 8) & 0xFF00) | ((n >> 8) & 0x00FF)) >> 5)
        if r > 2048:  # negative
            r = 2048 - r
        return r

    def read_celsius(self):
        return self.__read_raw() * 0.125

    def read_fahrenheit(self):
        return self.__read_raw() * 0.225 + 32
Beispiel #12
0
class EPuck:
    """Class for interfacing with a generic e-puck robot."""
    def __init__(self,
                 i2c_bus: Optional[int] = None,
                 i2c_address: Optional[int] = None):
        if i2c_bus is not None:
            self._bus = SMBus(i2c_bus)
        else:
            try:
                self._bus = SMBus(_EPUCK_I2C_CHANNEL)
            except FileNotFoundError:
                self._bus = SMBus(_EPUCK_LEGACY_I2C_CHANNEL)

        if i2c_address is not None:
            self._i2c_address = i2c_address
        else:
            self._i2c_address = _EPUCK_I2C_ADDRESS

        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(_EPUCK_RESET_PIN, GPIO.OUT, initial=GPIO.HIGH)

    def __del__(self):
        GPIO.cleanup(_EPUCK_RESET_PIN)

    def _write_data_8(self, address, data):
        self._bus.write_byte_data(self._i2c_address, address, data)

    def _write_data_16(self, address, data):
        self._bus.write_word_data(self._i2c_address, address, data)

    def _read_data_8(self, address):
        return self._bus.read_byte_data(self._i2c_address, address)

    def _read_data_16(self, address):
        return self._bus.read_word_data(self._i2c_address, address)

    @staticmethod
    def reset_robot():
        GPIO.output(_EPUCK_RESET_PIN, GPIO.LOW)
        sleep(0.1)
        GPIO.output(_EPUCK_RESET_PIN, GPIO.HIGH)
Beispiel #13
0
def range_dist():
    
    sonar=False
    lidar_sens=True # lidar sensing True, else EZ4 sonar or VL53L1X

    if sonar:
        # does not work well on grass
        from smbus import SMBus
##        i2cbus = SMBus(1)
        while True:
            try:
                i2cbus = SMBus(1)
                i2cbus.write_byte(0x70, 0x51)
                time.sleep(0.12)
                val = i2cbus.read_word_data(0x70, 0xE1)
                distance_in_cm=val>>8 | (val & 0x0F)<<8
##                print distance_in_cm, 'cm'
                print>>f,distance_in_cm,'cm'
                msg_sensor(distance_in_cm,25,400), #sonar facing down
                
            except IOError, err:
                print err

            time.sleep(0.1)
Beispiel #14
0
from smbus import SMBus

b = SMBus(1)  # 1 indicates /dev/i2c-1

dev_addr1 = 0x10
dev_addr2 = 0x11

general_purpose_register = 0x03
dac_pin_config_register = 0x05
dac_out0_register = 0x10

# set I/O0 of dev 0 to dac output
b.write_word_data(dev_addr1, dac_pin_config_register, 0x0001)

# set I/O0 to 1000/4095 -> 0x3e8
b.write_word_data(dev_addr1, dac_out0_register, 0x83e8)

print("{:x}".format(b.read_word_data(dev_addr1, general_purpose_register)))
Beispiel #15
0
class Machine:
    def __init__(self) -> None:
        self.currentState = Outputs(Motor.Halt, Plate.Off)
        self.bus = SMBus(1)

    def getSensorValues(self) -> Inputs:
        temp = self.tryRead(self.readObjectTempStable)
        top = self.readPin(TOUCH_SENSOR_TOP_PIN)
        bottom = self.readPin(TOUCH_SENSOR_BOTTOM_PIN)
        back = self.readPin(TOUCH_SENSOR_BACK_PIN)
        return Inputs(top=top, bottom=bottom, back=back, temp=temp)

    def controlDevices(self, controls: Outputs, force: bool = False) -> None:
        if force or controls.motor != self.currentState.motor:
            print(controls.motor)
            if controls.motor == Motor.Up:
                self.motorUp()
            if controls.motor == Motor.Down:
                self.motorDown()
            if controls.motor == Motor.Halt:
                self.motorHalt()
        if controls.plate != self.currentState.plate:
            self.switchPlateState()
        self.currentState = Outputs(controls.motor, controls.plate)

    def readPin(self, pin: int) -> bool:
        return GPIO.input(pin)

    def motorUp(self) -> None:
        GPIO.output(MOTOR_A_PIN, GPIO.LOW)
        GPIO.output(MOTOR_B_PIN, GPIO.HIGH)
        GPIO.output(MOTOR_E_PIN, GPIO.HIGH)

    def motorDown(self) -> None:
        GPIO.output(MOTOR_A_PIN, GPIO.HIGH)
        GPIO.output(MOTOR_B_PIN, GPIO.LOW)
        GPIO.output(MOTOR_E_PIN, GPIO.HIGH)

    def motorHalt(self) -> None:
        GPIO.output(MOTOR_A_PIN, GPIO.LOW)
        GPIO.output(MOTOR_B_PIN, GPIO.LOW)
        GPIO.output(MOTOR_E_PIN, GPIO.LOW)

    def turnRelayOn(self) -> None:
        GPIO.output(RELAY_PIN, GPIO.HIGH)

    def turnRelayOff(self) -> None:
        GPIO.output(RELAY_PIN, GPIO.LOW)

    def switchPlateState(self) -> None:
        self.turnRelayOn()
        time.sleep(PLATE_SWITCH_TIMEOUT)
        self.turnRelayOff()

    def getAverage(self, values: List[float]) -> float:
        return sum(values) / len(values)

    def read16(self, register: int) -> float:
        return self.bus.read_word_data(ADDRESS, register)

    def readTemp(self, register: int) -> float:
        return self.read16(register) * 0.02 - 273.15

    def readTempStable(self, register: int) -> float:
        values: List[float] = []
        numTries = 0
        while len(values) < NUM_VALUES_TO_AVERAGE_OVER:
            numTries += 1
            try:
                time.sleep(TIME_BETWEEN_TRIES)
                values.append(self.readTemp(register))
            except IOError as err:
                if numTries >= MAX_NUM_TRIES:
                    raise err
                continue
        error = max(values) - min(values)
        if error > MAX_ALLOWED_ERROR:
            raise InaccuracyError("High temperature deviation")
        return self.getAverage(values)

    def readObjectTempStable(self) -> float:
        return self.readTempStable(REGISTER_OBJECT_TEMP)

    def tryRead(self, readFunc: Callable[..., float]) -> float:
        try:
            return readFunc()
        except IOError as err:
            print("IO error")
            raise err
        except InaccuracyError as err:
            print("Inaccuracy error")
            raise err
        return 0

    def __enter__(self) -> None:
        GPIO.setmode(GPIO.BOARD)

        GPIO.setup(RELAY_PIN, GPIO.OUT)
        GPIO.setup(MOTOR_A_PIN, GPIO.OUT)
        GPIO.setup(MOTOR_B_PIN, GPIO.OUT)
        GPIO.setup(MOTOR_E_PIN, GPIO.OUT)
        GPIO.setup(TOUCH_SENSOR_TOP_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(TOUCH_SENSOR_BOTTOM_PIN,
                   GPIO.IN,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(TOUCH_SENSOR_BACK_PIN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        return self

    def __exit__(self, type: Any, value: Any, traceback: Any) -> Any:
        """Make sure we turn the plate off and clean up GPIO pins whenever we shut down."""
        self.motorHalt()
        if self.currentState.plate == Plate.On:
            self.switchPlateState()
        GPIO.cleanup()
Beispiel #16
0
#!/usr/bin/env python2.7

from smbus import SMBus
import time

bus = SMBus(1)
addr = 0x0b

t_end = time.time() + 60 * 15

while time.time() < t_end:
    try:
        voltage = bus.read_word_data(addr, 0x09)
        current = bus.read_word_data(addr, 0x0a)
        #temperature = bus.read_word_data(addr, 0x08)
        relsoc = bus.read_word_data(addr, 0x0d)
        adssoc = bus.read_byte_data(addr, 0x0e)
    except:
        continue

    print("Voltage: ")
    print(voltage)
    print("Current: ")
    print(current)
    print("Relsoc: ")
    print(relsoc)
    print("Adssoc: ")
    print(adssoc)

    time.sleep(1)
Beispiel #17
0
class MLX90614_IR_sensor():
	'''This class will read the IR temperatue values from the sensor'''
	def __init__(self, address):
		'''Initalizing all variables 
		'''
		#address working at 
		self.address = address
		
		
		#note that the default slave address is 0x00
		#TODO: how to detect several different addresses at once 
		#self.address = 0x5a 
		
		#Objec temperature address
		self.tobj_address = 0x27 #0x27
		
		#ambien temperature address
		self.tamb_address = 0x26 #0x26
				
		#smbus command setup
		self.bus = SMBus(1) 
		
		#inital ambient and object temperatures
		self.init_tamb_value = 0.0
		self.init_tobj_value = 0.0
		
		#inital tamb and tobj values converted to Celsius 
		self.tamb_ans= 0.0
		self.tobj_ans= 0.0
		
		#ambient temperature
		self.tamb_num = 0.0
		#object temperature
		self.tobj_num = 0.0
		
		self.tobj_percent_limit_up=0.0
		self.tobj_percent_limit_down=0.0
		self.tamb_percent_limit_up=0.0
		self.tamb_percent_limit_down=0.0
		
		#instantiate the config file and extract the dict 
		#opening the config file 
		self.config = config.config.Config()
		#reading the config file
		#self.config.readconfig() 
		#extract the slice and slice values 
		#print self.config.dict
		
		#dict length for data analysis
		self.length = int(self.config.dict['length'])
		#slice length of data analysis
		self.slice = int(self.config.dict['slice'])
		
		#importing the control_variable() class to obtain the jump and limit values
		self.control_class = mlx.control_variable.Control_Variable()
		self.control_class.run() 
		
		self.tobj_jump_value = 0.0 
		self.tamb_jump_value = 0.0 
		
		self.cycle = 0
		self.counter = 0
		
		self.tamb_data_analysis_list = []
		self.tobj_data_analysis_list = []
		
		self.tobj_data_analysis_result = []
		self.tamb_data_analysis_result = []
		
		#this is the record_list which is the varible passed to the gui 
		#note that we are initalizing all variables with 0 are the six variables are there
		#the appended list data is being stored to the log files, the gui will only show a subaspect of the data
		self.record_list = [0,0,0,0,0,0]
		self.record_dict = {self.address: []} #, 'cycle':self.cycle }

	def read(self):
		'''getting the values from the IR device sensor'''
		self.init_tobj_value = self.bus.read_word_data(self.address, self.tobj_address)
		#sleep for 200 ms the time for the sensor is at least 144 ms
		time.sleep(0.2)
			
		self.init_tamb_value = self.bus.read_word_data(self.address, self.tamb_address)
		#sleep for 200 ms the timer for the sensor is at least 144 ms 
		time.sleep(0.2)
	
	def object_temp_analysis(self):
		'''this function converts the object temperature from kelvin to celsius values'''
		#converting values from long bits into degrees celsius
		#using fomula in sensor datasheet manual
		#pg ?????
		
		#convert temperatures from kelvin to celsius
		tobj_ans = ( self.init_tobj_value*0.02 ) - 273.15
		#print tobj_ans
		self.tobj_ans = tobj_ans
		#mylog2.debug('Tobj: ' + repr(tobj_ans) )
		
		#calculate jump value 
		jump_value = tobj_ans - self.tobj_num #- tobj_ans
		#save calculated jump value to self value
		self.tobj_jump_value = jump_value
		
		#print 'obj jump: ', jump_value
		mylog2.debug('obj jump value: ' + repr(jump_value) )
		
		#comparing jump value to control jump value set by user
		if jump_value >= self.control_class.jump_value: 
			#reinitalize variables 
			self.tobj_num = tobj_ans
			#calculate percent limit 
			self.tobj_percent_limit_up = self.tobj_num*self.control_class.limit_value
			print '*****TOBJ UP*****'
			mylog2.debug('UP VALUE-Tobj:--> ' + 'object temperature value: '+ repr(self.tobj_num) + 
			'jump up value: ' + repr(jump_value) +'temp limit value: ' + repr(self.tobj_percent_limit_up)
			+ 'jump value: ' + repr(self.control_class.jump_value) )
			
		elif jump_value <= -(self.control_class.jump_value): 
			#reinitalize variables
			self.tobj_num = tobj_ans
			#calculating percent limit
			self.tobj_percent_limit_down = self.tobj_num*self.control_class.limit_value
			print '******TOBJ DOWN*****'
			mylog2.debug('DOWN VALUE-Tobj:--> ' + 'object temperature value: '+ repr(self.tobj_num) 
			+ 'jump up value: ' + repr(jump_value) +'temp limit value: ' + repr(self.tobj_percent_limit_down) 
			+'jump value: ' + repr(self.control_class.jump_value))
			
		else:
			print 'no change'
		
	def ambient_temp_analysis(self):
		'''this function records the ambient temperatuer and converts the value to degrees celsisus
		'''
		tamb_ans = ( self.init_tamb_value*0.02 ) - 273.15
		#print tamb_ans
		#mylog2.debug('tamb ans: ' + repr(tamb_ans) )
		self.tamb_ans = tamb_ans
		
		#calculate jump value 
		jump_value = tamb_ans - self.tamb_num #- tamb_ans
		#print 'amb jump: ', jump_value
		
		if jump_value >= self.control_class.jump_value: 
			#assuming the value is + 
			#reinitalize varialbes 
			self.tamb_num = tamb_ans
			
			#calculate percent limit 
			tamb_percent_limit_up = self.tamb_num*self.control_class.limit_value
			
			print '*********TAMB UP***********'
			
			mylog2.debug('UP VALUE-Tamb:-->' + 'Ambient temperature value: '+ repr(self.tamb_num) 
			+ 'jump up value: ' + repr(jump_value) +'temp limit value: ' 
			+ repr(self.tamb_percent_limit_up) + 'jump value: ' + repr(self.control_class.jump_value))
		
		elif jump_value <= -(self.control_class.jump_value): 
			#reinitalize variables
			self.tamb_num = tamb_ans
			#calculate percent limit 
			tamb_percent_limit_down = self.tamb_num*self.control_class.limit_value
			
			print '*********TAMB DOWN***********'
			
			mylog2.debug('DOWN VALUE-Tamb' + 'Ambient temperature value: '+ repr(self.tamb_num) 
			+ 'jump up value: ' + repr(jump_value) +'temp limit value: ' 
			+ repr(self.tamb_percent_limit_down) + 'jump value: ' + repr(self.control_class.jump_value))
		
		else:
			print 'no change'
	
	def data_analysis(self):
		'''This function does the data analysis for the data
		'''
		#appending items to list 
		self.tobj_data_analysis_list.append(self.tobj_ans) #_num)
		self.tamb_data_analysis_list.append(self.tamb_ans) #num)
		
		if len(self.tobj_data_analysis_list) > self.length: #15:
			#if the length is greater then 50
			for item in self.tobj_data_analysis_list[:self.slice]: #10]:
				#take out the first 20 items and pop them out 
				self.tobj_data_analysis_list.pop(0)
		
		if len(self.tamb_data_analysis_list) > self.length: #15:
			#pop out the first 20 items in the list 
			for item in self.tamb_data_analysis_list[:self.slice]: #10]:
				self.tamb_data_analysis_list.pop(0)
		
		#doing tobject calculations
		tobj_min = min(self.tobj_data_analysis_list[ -self.slice: ] )  #[-5:])
		tobj_max = max(self.tobj_data_analysis_list[ -self.slice: ] ) #[-5:])
		tobj_sum = sum(self.tobj_data_analysis_list[ -self.slice: ] ) #[-5:])
		tobj_len = len(self.tobj_data_analysis_list) #[ -self.slice: ] ) #[-5:])
		tobj_avg = tobj_sum/tobj_len
		 
		#doign tambient claculations 
		tamb_min = min(self.tamb_data_analysis_list[ -self.slice: ] ) #[-5:])
		tamb_max = max(self.tamb_data_analysis_list[ -self.slice: ] ) #[-5:])
		tamb_sum = sum(self.tamb_data_analysis_list[ -self.slice: ] ) #[-5:])
		tamb_len = len(self.tamb_data_analysis_list) #[ -self.slice: ] ) #[-5:])
		tamb_avg = tamb_sum/tobj_len
		
		self.record_list=[tobj_min, tobj_max, tobj_avg, tamb_min, tamb_max, tamb_avg, tobj_len, tamb_len]
		
		#logging the data
		mylog2.debug('Record list: ' + repr(self.record_list) )
		
		
		
	
	def record_data(self):
		'''this function saves the data to csv files note that this data is not needed and necessary
		TODO: Deprecated function '''
		myfile = open(FILENAME, 'a')
		newrow = time.strftime('%H:%M:%S,')
		newrow += str(self.cycle) + ","
		newrow += str(self.address) + ","  
		newrow += str(self.tobj_ans) + ","  
		newrow += str(self.tamb_ans) 
		newrow += NEWLINE
		myfile.write(newrow)
		myfile.close()
		
	def run(self):
		''''Function which runs the value'''
		#runt the control class to ensure the varaibles are set right and can be changed as needed
		#self.control_class.run()
		mylog2.debug('control variable values: ' + repr(self.control_class.jump_value) + 
							"--" + repr(self.control_class.limit_value) )
		self.cycle+=1
		print 
		
		print 'Time: ', time.strftime('%H:%M:%S,')
		print 'cycle: ', self.cycle
		
		self.read()
		self.object_temp_analysis()
		self.ambient_temp_analysis()
		self.data_analysis()
		self.record_data()

		print 'Address: %s -- tobject: %s -- tambient: %s'%(self.address, self.tobj_num, self.tamb_num)
		
		#log the results
		mylog2.debug('tamb data analysis: ' + repr(self.tamb_data_analysis_result)  )
Beispiel #18
0
class ads1015:
    def __init__(self, addr=0x48):
        self.i2c = SMBus(1)
        self.addr = addr
        self.constants()
        self.mux = self.get(self.MUX)
        self.gain = self.get(self.GAIN)
        self.mode = self.get(self.MODE)
        self.data_rate = self.get(self.DATA_RATE)
        self.comp_mode = self.get(self.COMP_MODE)
        self.comp_pol = self.get(self.COMP_POL)
        self.comp_lat = self.get(self.COMP_LAT)
        self.comp_que = self.get(self.COMP_QUE)

    def constants(self):
        # Register adresses
        self.CONV_REG = 0b00
        self.CONFIG_REG = 0b01
        self.LO_TRESH_REG = 0b10
        self.HI_TRESH_REG = 0b11
        # Input MUX
        self.MUX = (12, 3, 'mux')
        self.MUX_DIFF_01 = 0b000
        self.MUX_DIFF_03 = 0b001
        self.MUX_DIFF_13 = 0b010
        self.MUX_DIFF_23 = 0b011
        self.MUX_0 = 0b100
        self.MUX_1 = 0b101
        self.MUX_2 = 0b110
        self.MUX_3 = 0b111
        # Gain
        self.GAIN = (9, 3, 'gain')
        self.GAIN_0 = 0b000  # +/-6.144V
        self.GAIN_1 = 0b001  # +/-4.096V
        self.GAIN_2 = 0b010  # +/-2.048V
        self.GAIN_3 = 0b011  # +/-1.024V
        self.GAIN_4 = 0b100  # +/-0.512V
        self.GAIN_5 = 0b101  # +/-0.256V
        self.VRANGE = [6.144, 4.096, 2.048, 1.024, 0.512, 0.256]
        # Conversion mode
        self.MODE = (8, 1, 'mode')
        self.MODE_CONTINUOUS = 0b0
        self.MODE_SINGLE_SHOT = 0b1
        # Data rate
        self.DATA_RATE = (5, 3, 'data_rate')
        self.DATA_RATE_128SPS = 0b000
        self.DATA_RATE_250SPS = 0b001
        self.DATA_RATE_490SPS = 0b010
        self.DATA_RATE_920SPS = 0b011
        self.DATA_RATE_1600SPS = 0b100
        self.DATA_RATE_2400SPS = 0b101
        self.DATA_RATE_3300SPS = 0b110
        # Comperator mode
        self.COMP_MODE = (4, 1, 'comp_mode')
        self.COMP_MODE_NORMAL = 0b0
        self.COMP_MODE_WINDOW = 0b1
        # Comperator polarity
        self.COMP_POL = (3, 1, 'comp_pol')
        self.COMP_POL_NORMAL = 0b0
        self.COMP_POL_INVERTED = 0b1
        # Comperator latching
        self.COMP_LAT = (2, 1, 'comp_lat')
        self.COMP_LAT_OFF = 0b0
        self.COMP_LAT_ON = 0b1
        # Comperator queue
        self.COMP_QUE = (0, 2, 'comp_que')
        self.COMP_QUE_1 = 0b00
        self.COMP_QUE_2 = 0b01
        self.COMP_QUE_4 = 0b10
        self.COMP_QUE_OFF = 0b11

    def bitwrite16(self, word, value, bitshift, bitwidth):
        return ((word & (0xFFFF - ((2**bitwidth - 1) << bitshift))) |
                (value << bitshift))

    def byteswap(self, word):
        return ((word >> 8) & 0x00FF) + ((word << 8) & 0xFF00)

    def get(self, parameter):
        config = self.byteswap(
            self.i2c.read_word_data(self.addr, self.CONFIG_REG))
        return (config >> parameter[0]) & (2**parameter[1] - 1)

    def set(self, parameter, value):
        config = self.byteswap(
            self.i2c.read_word_data(self.addr, self.CONFIG_REG))
        config = self.bitwrite16(
            config, value, bitshift=parameter[0],
            bitwidth=parameter[1]) & 0x7FFF
        self.i2c.write_word_data(self.addr, self.CONFIG_REG,
                                 self.byteswap(config))
        setattr(self, parameter[2], value)

    def convert(self):
        config = self.byteswap(
            self.i2c.read_word_data(self.addr, self.CONFIG_REG))
        config = config | 0x8000
        self.i2c.write_word_data(self.addr, self.CONFIG_REG,
                                 self.byteswap(config))

    def isconverting(self):
        config = self.byteswap(
            self.i2c.read_word_data(self.addr, self.CONFIG_REG))
        return ((config & 0x8000) == 0)

    def read(self, mux=None):
        if mux in [0, 1, 2, 3, 4, 5, 6, 7]:
            self.set(self.MUX, mux)
        if self.mode == self.MODE_SINGLE_SHOT:
            self.convert()
            while self.isconverting():
                pass
        return self.byteswap(self.i2c.read_word_data(self.addr, self.CONV_REG))

    def voltage(self, mux=None):
        return self.read(mux) * self.VRANGE[self.gain] / 0x7FFF

    def set_input(self, pin=None):
        if pin in [0, 1, 2, 3]:
            self.set(self.MUX, pin + 4)

    def set_gain(self, gain=None):
        if gain in [0, 1, 2, 3, 4, 5]:
            self.set(self.GAIN, gain)
Beispiel #19
0
 def _readWordPMBus(self, cmd, pecByte=True):
     bus = SMBus(self.busID)
     bus.pec = pecByte
     data = bus.read_word_data(self.address, cmd)
     bus.close()
     return data
I2CAdress = 0x40

# command codes ( datasheet_Sensirion_Humidity_Sensors_SHT21_Datasheet_V4.pdf __page 8 __ Table 6 )
TEM = 0xE3
HUM = 0xE5
WRITE_USER_REGISTER = 0xE6
READ_USER_REGISTER = 0xE7

# command codes special ( datasheet_Sensirion_Humidity_Sensors_SHT2x_Electronic_Identification_Code_V1.1 )
CMD_ID = 0xFA0F

#THe I2C bus use on raspberry PI3
bus = SMBus(1)

#reading the identification numbers
ID_number = bus.read_word_data(I2CAdress, CMD_ID)
print format(ID_number, '04x')
sleep(0.1)

# Set the resolution to better possible : 0x02 --> 14 bits for temperature and 12 bits for humidity (datasheet_Sensirion_Humidity_Sensors_SHT21_Datasheet_V4.pdf __page 9 __ Table 8)
bus.write_byte_data(I2CAdress, WRITE_USER_REGISTER, 0x02)
# Read the user register for see if the resolution is like the specification
user_register = bus.read_byte_data(I2CAdress, READ_USER_REGISTER)
print format(user_register, '02x')

# reading raw humidity registers
raw_humidity = bus.read_word_data(I2CAdress, HUM)
data_humidity = [(raw_humidity & 0xFF), ((raw_humidity >> 8) & 0xFF)]
#print data_humidity

# reading raw temperature registers
Beispiel #21
0
class bq34z100g1(object):

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

    @staticmethod
    def log(msg):
        print(msg)

    @staticmethod
    def ftol(byte: int):
        liste = []
        liste.append(1) if byte & 1 > 0 else liste.append(0)
        liste.append(1) if byte & 2 > 0 else liste.append(0)
        liste.append(1) if byte & 4 > 0 else liste.append(0)
        liste.append(1) if byte & 8 > 0 else liste.append(0)
        liste.append(1) if byte & 16 > 0 else liste.append(0)
        liste.append(1) if byte & 32 > 0 else liste.append(0)
        liste.append(1) if byte & 64 > 0 else liste.append(0)
        liste.append(1) if byte & 128 > 0 else liste.append(0)
        return liste

    def openConfig(self):
        self._bus.write_word_data(self._address, 0x00, 0x0414)
        self._bus.write_word_data(self._address, 0x00, 0x3672)
        self._bus.write_byte_data(self._address, 0x61, 0x00)

    def setConfig(self):
        self.openConfig()
        self._bus.write_byte_data(self._address, 0x3e, 0x30)
        self._bus.write_byte_data(self._address, 0x3f, 0x00)
        # self._bus.write_byte_data(self._address, 0x4a, 0x00)
        # self._bus.write_byte_data(self._address, 0x4b, 0x00)

    def _writeValue(self, cmd, text):
        try:
            self._bus.write_word_data(self._address, cmd, text)
        except:
            bq34z100g1.log("Couldn't write to i2c bus")

    def _readValue(self, register: int, length: int = 2) -> int:
        try:
            if length == 2:
                return self._bus.read_word_data(self._address, register)
            if length == 1:
                return self._bus.read_byte_data(self._address, register)
            else:
                print("is not supported by now") # do again two times?
                return -1
        except:
            bq34z100g1.log("Could not read i2c bus")
            return -1

    def _readSignedValue(self, register: int, length: int = 2) -> int:
        value = self._readValue(register, length)
        if length == 2:
            if value <= 32767:
                return value
            else:
                return value - 65535
        if length == 1:
            if value <= 128:
                return value
            else:
                return value - 256

    def get_temperature(self):  # 0x0c
        """returns Temperature in °C"""
        return round((self._readValue(0x0C) * 0.1) - 273.15, 2)

    def get_internal_temperature(self):  # 0x2a
        """return internal Temperature in °C"""
        return round((self._readValue(0x2A) * 0.1) - 273.15, 2)

    def get_voltage(self):  # 0x08,0x09
        """return Voltage in mV"""
        return self._readValue(0x08)

    def get_current(self):  # 0x10,0x11
        """returns Current in mA"""
        return self._readSignedValue(0x10)

    def get_power(self):  # 0x26,0x27
        """returns current Power Usage"""
        return self._readSignedValue(0x26)

    def get_capacity(self):  # 0x04,0x05
        """returns Capacity in mAh"""
        return self._readValue(0x04)

    def get_full_capacity(self):  # 0x06,0x07
        """returns Capacity when full in mAh"""
        return self._readValue(0x06)

    def get_design_capacity(self):  # 0x0c,0x0d
        """returns Design Capacity in mAh"""
        return self._readValue(0x3C)

    def get_cycle_count(self):  # 0x2c
        """returns the amount of Cycles the Battery has run"""
        return self._readValue(0x2C, 1)

    def get_state_of_charge(self):  # 0x02
        """return State of Charge in %"""
        return self._readValue(0x02, 1)

    def get_flagsa(self):  #0x0e, 0x0f
        return str(str(self.ftol(int(self._readValue(0x0e, 1)))) + "\n" + str(self.ftol(int(self._readValue(0x0f, 1)))))

    def get_flagsb(self):  #0x12, 0x13
        return str(str(self.ftol(int(self._readValue(0x12, 1)))) + "\n" + str(self.ftol(int(self._readValue(0x13, 1)))))

    def get_ctrl_statusa(self):
        return self.ftol(int(self._readValue(0x00, 1)))

    def get_ctrl_statusb(self):
        return self.ftol(int(self._readValue(0x01, 1)))

    def get_max_error(self):
        return self._readValue(0x03, 1)

    def get_avg_time_to_empty(self):
        return self._readValue(0x18)

    def get_avg_time_to_full(self):  # 0x1a,0x1b
        return self._readValue(0x1A)

    def get_state_of_health(self):  # 0x2e,0x2f
        return self._readValue(0x2E)

    def get_qmax_time(self):
        return self._readValue(0x74)

    def get_learned_status(self):
        return self.ftol(int(self._readValue(0x63,1)))
Beispiel #22
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 smbus 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)
        return self._servo_us_to_degrees(us, us_min, us_max)

    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)
        return self._servo_us_to_degrees(us, us_min, us_max)

    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
Beispiel #23
0
     p.ChangeFrequency(note[0])
     sleep(note[1])
 p.stop()
 p.ChangeFrequency(N_BOUNCE)
 for led in LEDS: gpio.setup(led, gpio.OUT)
 oldBugger = WIDTH * HEIGHT * [None]
 oldTime = time()
 counter = 0
 sorry = True
 while 1:
     newTime = time()
     counter += newTime - oldTime
     if newTime - sfxStartTime > sfxLength:
         p.stop()
     adc.write_byte(33, 128)
     knob = adc.read_word_data(33, 0)
     knob = ((knob & 15) << 8 | knob >> 8) - 683
     if knob < 0: knob = 0
     elif knob > 2730: knob = 2730
     Player0Bat = HEIGHT - int(round(knob * (HEIGHT - Player0Height) / 2731.)) - Player0Height
     if sorry:
         knob = adc.read_byte_data(36,0) - 9
         if knob < 0: knob = 0
         elif knob > 220: knob = 220
         Player1Bat = HEIGHT - int(round(knob * (HEIGHT - Player1Height) / 220.)) - Player1Height
         gpio.output(17, 1)
         gpio.output(17, 0)
     sorry = not sorry
     if Player0SizeCounter < 15: Player0SizeCounter += newTime - oldTime
     else: Player0Height = 3
     if Player1SizeCounter < 15: Player1SizeCounter += newTime - oldTime
Beispiel #24
0
class SHT21 :
    RHmeasure_noHold = 0xF5
    Tmeasure_noHold  = 0xF3
    RHmeasure_Hold   = 0xE5
    Tmeasure_Hold    = 0xE3
    Soft_Reset       = 0xFE
    Write_Reg        = 0xE6
    Read_Reg         = 0xE7
##############################################################################
##  Experimental register found by looking for each one individually        ##
##  with a 10 seconds wait between each try. CheckCRC says true for all.    ##
    RH_Reg           = 0x05                                                 ##
    T_Reg            = 0x03                                                 ##
##  read_reg?          0x06                                                 ##
##  read_reg           0x07                                                 ##
##  unknown            0x09     result was 6,0,90(constant over time)       ##
##  unknown            0x0F     result was 2,68,32(constant over time)      ##
##  serial number?     0x1A     periodic on 64 bits?                        ##
##  result was      [25, 203, 218, 223, 71, 170, 137, 242, 217, 140, 232    ##
##                  , 120, 231, 86, 128, 122, 7, 151, 248, 59, 252, 255,    ##
##                  232, 120, 54, 99, 129, 75, 30, 92, 80, 126]             ##
##  serial number?     0x1B     same as 0x1A with random shift              ##
##  T_reg?             0xE3     result was 103,88,60(made a new measure?)   ##
##  RH_reg?            0xE5     result was 83,206,146(new measure?)         ##
##  read_reg           0xE6     result was 58,30                            ##
##  read_reg           0xE7     result was 58,30                            ##
##  unknown            0xE9     result was 6,0,90                           ##
##  unknown            0xEF     result was 2,68,32                          ##
##  serial number      0xFA     same as 1A, check sensirion(says 64 bits ID)##
##  serial number?     0xFB     same as 1B                                  ##
##  device ID?         0xFF     check i2c full specs, results seems random  ##
############################1#################################################
    class CRCError(Exception):
        pass

    def __init__(self, addr, busnum = 1) :
        self.address = addr
        self.bus = SMBus(busnum)
        #self.bus.open(busnum)
        self.Reset()
        #reg = self.ReadReg()
        reg = 0
        if (reg & 0x80) and (reg & 0x01):
            self.RH_res = 11
            self.T_res  = 11
        elif (reg & 0x80) and not(reg & 0x01):
            self.RH_res = 10
            self.T_res  = 13
        elif not(reg & 0x80) and not(reg & 0x01):
            self.RH_res = 12
            self.T_res  = 14
        else:
            self.RH_res = 8
            self.T_res  = 12

    def getRH(self):
        self.bus.write_byte(self.address, self.RHmeasure_noHold)
        time.sleep(0.1)
        RH = self.bus.read_i2c_block_data(self.address, self.RH_Reg, 3)
        #print RH
        if self.CheckCRC(RH):
            self.RHum = RH
            RH[1] &= ~0x03      #reset 2 status bits(LSB)
            return -6+125.*(RH[0]*256+RH[1])/65536.
        else:
            #print 'CRC checksum failed, data was corrupted(RH reading)'
            #return -1
            raise self.CRCError


    def getT(self):
        self.bus.write_byte(self.address, self.Tmeasure_noHold)
        time.sleep(0.1)
        T = self.bus.read_i2c_block_data(self.address, self.T_Reg, 3)
        #print T
        if self.CheckCRC(T):
            self.Temp = T
            T[1] &= ~0x03       #reset 2 status bits(LSB)
            return -46.85+175.72*(T[0]*256+T[1])/65536.
        else:
            #print 'CRC checksum failed, data was corrupted(temp reading)'
            #return -1
            raise self.CRCError
    
    def Reset(self):
        self.bus.write_byte(self.address, self.Soft_Reset)
        time.sleep(0.02) #must wait 15ms

    def ReadReg(self):
        reg = self.bus.read_word_data(self.address, self.Read_Reg)
        crc = [ reg & 0xFF, (reg & 0xFF00) >> 8]
        
        if self.CheckCRC(crc):
            return reg & 0xFF
        else:
            #print 'Error : CRC not matching !'
            #return 0
            raise self.CRCError
        
    def WriteReg(self, val):
        reg = self.ReadReg()
        reg &= 0x38
        self.bus.write_byte_data(self.address, self.Write_Reg, val)

    def test(self):
        self.T = []
        self.getRH()
        self.getT()
        for i in range(256):
            try :
                time.sleep(10)
                self.T.append((hex(i), self.bus.read_i2c_block_data(sensor.address, i)))
                print(hex(i), 'success reading')
            except IOError as err:
                print(hex(i), 'failed reading')
        return self.T

    def CheckCRC(self, buf):
        poly = 0x131
        crc = 0
        #print buf[2]
        for by in buf:
            crc ^= by
            for i in range(8):
                if crc & 0x80 :
                    crc = (crc << 1)^poly
                else:
                    crc <<= 1
                #print crc
        return crc==0
Beispiel #25
0
 def getCurrent(self):
     bus = SMBus(1)
     self.current = self.decodePMBus(bus.read_word_data(self.address, 0x8C))
     bus.close()
     return self.current
Beispiel #26
0
 def getVoltageOut(self):
     bus = SMBus(1)
     voltageOutMessage = bus.read_word_data(self.address, 0x8B)
     bus.close()
     self.voltageOut = voltageOutMessage * (2.0**self.VOUT_N)
     return self.voltageOut
Beispiel #27
0
 def getVoltageIn(self):
     bus = SMBus(1)
     self.voltageIn = self.decodePMBus(
         bus.read_word_data(self.address, 0x88))
     bus.close()
     return self.voltageIn
class SRF02:
    def __init__(self):

        self._i2c = SMBus(1)
        self._i2c_address = SRF02_I2C_ADDRESS
        self._waiting_for_echo = False

        yesterday = datetime.now() - timedelta(1)
        self._time_last_burst = yesterday

        # The last distance measurement
        self.distance = None  # meters

        # On power up, the detection threshold is set to 28cm (11")
        self.mindistance = 0.28  # meters

        # This is mostly for debugging and testing
        self.num_bursts_sent = 0

        # check that the sensor is present - read the version
        self.version = self._read_version()
        log.info("SRF-02 Ultrasonic Sensor initialized. Version: %d" % self.version)

        # we want to check how often we get exceptions
        self.error_counter = 0

    # Should be called in some sensor loop, maybe at 100Hz. Is fast.
    # Will trigger an ultrasonic burst or check if we received an echo.
    # I we have a measurement, it is returned in meters.
    def update(self):

        distance = None

        now = datetime.now()
        time_since_last_burst = (now - self._time_last_burst).total_seconds()

        #        log.debug("time since last burst: {}".format(time_since_last_burst))

        if self._waiting_for_echo:
            # make sure we wait at least some amount of time before we read
            if time_since_last_burst > SRF02_MIN_TIME_BETWEEN_BURST_READ:
                # check if we have an echo
                distance = self._read_echo()

            # Fallback if we don't get an echo, just stop waiting
            # from the data sheet:
            # The SRF02 will always be ready 70mS after initiating the ranging.
            if distance is None and time_since_last_burst > SRF02_MAX_WAIT_TIME:
                log.warn("Fallback! Waited longer than 70ms!")
                self._waiting_for_echo = False

        if (not self._waiting_for_echo) and time_since_last_burst > SRF02_MIN_TIME_BETWEEN_BURSTS:
            self._send_burst()

        expected_error = self._calc_expected_error(distance)

        return distance, expected_error

    def _send_burst(self):
        self._i2c.write_byte_data(self._i2c_address, 0, 0x51)
        self._waiting_for_echo = True
        self._time_last_burst = datetime.now()
        self.num_bursts_sent += 1
        log.debug("Burst sent.")

    def _read_echo(self):
        # it must be possible to read all of these data in 1 i2c transaction
        # buf[0] software version. If this is 255, then the ping has not yet returned
        # buf[1] unused
        # buf[2] high byte range
        # buf[3] low byte range
        # buf[4] high byte minimum auto tuned range
        # buf[5] low byte minimum auto tuned range

        # We use the version information to detect if the result is there yet.
        # 255 is a dummy version for the case that no echo has been received yet. For me, the real version is "6".
        if self._read_version() == 255:
            log.debug("Version is 255")
            return None

        self.distance = self._i2c.read_word_data(self._i2c_address, 2) / 255 / 100
        self.mindistance = self._i2c.read_word_data(self._i2c_address, 4) / 255 / 100

        # A value of 0 indicates that no objects were detected. We prefer None to represent this.
        if self.distance == 0:
            self.distance = None

        self._waiting_for_echo = False
        log.debug("echo received! distance is: {}".format(self.distance))

        return self.distance

    # The version can be read from register 0.
    # Reading it has no real value for us, but we can use it to determine if a measurement is finished or not.
    def _read_version(self):
        try:
            return self._i2c.read_byte_data(self._i2c_address, 0)

            # 255 means that the unit is still measuring the distance
        except IOError:
            log.error("Recovering from IOError")
            self.error_counter += 1
            return 255

    # find out what kind of error we expect (used in sensor fusion)
    def _calc_expected_error(self, distance):

        # no reading at all
        if distance is None:
            return SENSOR_ERROR_MAX

        # object too close
        if distance <= self.mindistance:
            return SRF02_SENSOR_ERROR_LOW_RANGE

        # good distance, nice measurement
        elif distance <= SRF02_MAX_RANGE:
            return SRF02_SENSOR_ERROR_GOOD_RANGE

        # object too far
        else:
            return SRF02_SENSOR_ERROR_HIGH_RANGE
from smbus import SMBus
from time import sleep

x = 1
while True:
 try:
  i2cbus = SMBus(1)
  i2cbus.write_byte(0x70, 0x51)
  sleep(0.12)
  val = i2cbus.read_word_data(0x70, 0xe1)

  print (val >> 8) & 0xff | (val>>8 & 0xff), 'cm'
from smbus import SMBus
from time import sleep

i2c = SMBus(1)

while True:
	try:
  		i2c.write_byte(0x70, 0x51)
  		sleep(0.3)
  		datin = i2c.read_word_data(0x70, 0xe1)
  		print ((datin >> 8) & 0x00ff) | ((datin << 8) & 0xff00), 'cm'
	except:
  		print err
Beispiel #31
0
class weather():
	_cal_AC1 = 0
	_cal_AC2 = 0
	_cal_AC3 = 0
	_cal_AC4 = 0
	_cal_AC5 = 0
	_cal_AC6 = 0
	_cal_B1 = 0
	_cal_B2 = 0
	_cal_MB = 0
	_cal_MC = 0
	_cal_MD = 0
	bmp180 = 0
	bh1750 = 0
	lm75addr = 0
	i2c1 = 0
	db = 0
	api = 0
	feed = 0
	tempds = 0
	lightds = 0
	pressds = 0
		

	def __init__(self):
		self.lm75addr = 0x4f
		self.bmp180 = 0x77
		self.bh1750 = 0x23
		self.i2c1 = SMBus(1)
		self.calibration()

	def calibration(self):
		self._cal_AC1 = self.read_16bit_regs(self.bmp180, 0xaa)
		self._cal_AC2 = self.read_16bit_regs(self.bmp180, 0xac)
		self._cal_AC3 = self.read_16bit_regs(self.bmp180, 0xae)
		self._cal_AC4 = self.read_16bit_regu(self.bmp180, 0xb0)
		self._cal_AC5 = self.read_16bit_regu(self.bmp180, 0xb2)
		self._cal_AC6 = self.read_16bit_regu(self.bmp180, 0xb4)
		self._cal_B1 = self.read_16bit_regs(self.bmp180, 0xb6)
		self._cal_B2 = self.read_16bit_regs(self.bmp180, 0xb8)
		self._cal_MB = self.read_16bit_regs(self.bmp180, 0xba)
		self._cal_MC = self.read_16bit_regs(self.bmp180, 0xbc)
		self._cal_MD = self.read_16bit_regs(self.bmp180, 0xbe)

	def readRawTemp(self):
		self.i2c1.write_byte_data(self.bmp180, 0xf4, 0x2e)
		time.sleep(0.005)
		raw = self.read_16bit_regu(self.bmp180, 0xf6)
		return raw

	def readTemperature(self):
		ut = self.readRawTemp()
		x1 = ((ut - self._cal_AC6) * self._cal_AC5) >> 15
		x2 = (self._cal_MC << 11) / (x1 + self._cal_MD)
		b5 = x1 + x2
		temp = ((b5 + 8) >> 4)/10.0
		return temp
	
	def readRawPressure(self):
		self.i2c1.write_byte_data(self.bmp180, 0xf4, 0xf4) #Read ultra high resolution
		time.sleep(0.026)
		msb = self.i2c1.read_byte_data(self.bmp180, 0xf6)
		lsb = self.i2c1.read_byte_data(self.bmp180, 0xf7)
		xlsb = self.i2c1.read_byte_data(self.bmp180, 0xf8)
		raw = (msb << 16) + (lsb << 8) + (xlsb) >> 5
		return raw
	
	def readPressure(self):
		# Get raw temperature and pressure
		ut = self.readRawTemp()
		up = self.readRawPressure()
		# Convert to actual compensated and calibrated pressure (see Datasheet)
		x1 = ((ut - self._cal_AC6) * self._cal_AC5) >> 15
		x2 = (self._cal_MC << 11) / (x1 + self._cal_MD)
		b5 = x1 + x2
		b6 = b5 - 4000
		x1 = (self._cal_B2 * (b6 * b6) >> 12) >> 11
		x2 = (self._cal_AC2 * b6) >> 11
		x3 = x1 + x2
		b3 = (((self._cal_AC1 * 4 + x3) << 3) + 2) / 4
	
		x1 = (self._cal_AC3 * b6) >> 13
		x2 = (self._cal_B1 * ((b6 * b6) >> 12)) >> 16
		x3 = ((x1 + x2) + 2) >> 2
		b4 = (self._cal_AC4 * (x3 + 32768)) >> 15
		b7 = (up - b3) * (50000 >> 3)
	
		if (b7 < 0x80000000):
			p = (b7 * 2) / b4
		else:
			p = (b7 / b4) * 2
		x1 = (p >> 8) * (p >> 8)
		x1 = (x1 * 3038) >> 16
		x2 = (-7357 * p) >> 16
		p = p + ((x1 + x2 + 3791) >> 4)
		return p

	def readLM75Temperature(self):
		# Measure temperature
		temp = self.i2c1.read_word_data(self.lm75addr,0)
		# Swap lower and higher byte
		temp = (((temp & 0xff) << 8)|((temp >> 8) & 0xff))
		value = temp >> 5
		# Make signed integer
		if (temp & 0x8000):
			# one's complement
			value = (~value & 0x1FF)
			# two's complement
			value = value - 1
			# significance: means negative temp
			value = -value
		value = value / 8.0
		return value

	def readBH1750Light(self):
		# Measure light
		luxtmp = self.i2c1.read_word_data(self.bh1750, 0x10)
		# Convert to actual lux (see Datasheet)
		lux = (((luxtmp >> 8) & 0xff) | ((luxtmp & 0xff) << 8))/1.2
		return lux

	def measure(self):
		thisdate = datetime.datetime.utcnow()
		temperature = self.readLM75Temperature()
		lux = self.readBH1750Light()
		pressure = float(self.readPressure()/100)
		return {'time':str(thisdate), 'temp':round(temperature,2), 'light':round(lux,2), 'pressure':round(float(pressure),2)}

	def print_climate(self):
		print "The temperature is: %i Degrees Celsius" % (self.readLM75Temperature())
		print "The light intensity is: %i Lux" % (self.readBH1750Light())
		print "The pressure is: %i Pascal" % (self.readPressure())		
	
	def read_16bit_regu(self, address, register):
		a = self.i2c1.read_byte_data(address, register)
		b = self.i2c1.read_byte_data(address, register+1)
		return ((a << 8) | b)

	def read_16bit_regs(self, address, register):
		a = self.i2c1.read_byte_data(address, register)
		b = self.i2c1.read_byte_data(address, register+1)
		c = (a << 8)|b
		if (c & 0x8000):
			c = (~c & 0xffff)
			c = c-1
			c = -c
		return c	
def sigint_handle(signal_recieved, frame):
    running = False


signal(SIGINT, sigint_handle)

# Create I2C bus
bus = SMBus(1)

INIT_SIGNAL = 0x01  #init signal fori2c
while (running):

    # NOTE: May need to move [D040] <= 0x06 inside the loop here, but I don't think you do

    sleep(SENSOR_MEASUREMENT_WAIT_TIME)

    # Tell the sensor we want to read the flow value [D051/D052] => Read Compensated Flow value
    answer = bus.read_word_data(PRESSURE_SENSOR_ADDRESS, INIT_SIGNAL)

    #bit  shift to get the full value
    answer = float((((answer & 0x00FF) << 8) + ((answer & 0xFF00) >> 8)))

    pressure = (answer - SENSOR_COUNT_MIN) * (
        SENSOR_PRESSURE_MAX - SENSOR_PRESSURE_MIN) / (
            SENSOR_COUNT_MAX - SENSOR_COUNT_MIN) + SENSOR_PRESSURE_MIN
    # Output for the user
    print(f"Sensor Reading {pressure:.3f} psi" + " " * 20, end='\r')

print("Exiting program...")
bus.close()
Beispiel #33
0
class SHT21:
    RHmeasure_noHold = 0xF5
    Tmeasure_noHold = 0xF3
    RHmeasure_Hold = 0xE5
    Tmeasure_Hold = 0xE3
    Soft_Reset = 0xFE
    Write_Reg = 0xE6
    Read_Reg = 0xE7
    ##############################################################################
    ##  Experimental register found by looking for each one individually        ##
    ##  with a 10 seconds wait between each try. CheckCRC says true for all.    ##
    RH_Reg = 0x05  ##
    T_Reg = 0x03  ##

    ##  read_reg?          0x06                                                 ##
    ##  read_reg           0x07                                                 ##
    ##  unknown            0x09     result was 6,0,90(constant over time)       ##
    ##  unknown            0x0F     result was 2,68,32(constant over time)      ##
    ##  serial number?     0x1A     periodic on 64 bits?                        ##
    ##  result was      [25, 203, 218, 223, 71, 170, 137, 242, 217, 140, 232    ##
    ##                  , 120, 231, 86, 128, 122, 7, 151, 248, 59, 252, 255,    ##
    ##                  232, 120, 54, 99, 129, 75, 30, 92, 80, 126]             ##
    ##  serial number?     0x1B     same as 0x1A with random shift              ##
    ##  T_reg?             0xE3     result was 103,88,60(made a new measure?)   ##
    ##  RH_reg?            0xE5     result was 83,206,146(new measure?)         ##
    ##  read_reg           0xE6     result was 58,30                            ##
    ##  read_reg           0xE7     result was 58,30                            ##
    ##  unknown            0xE9     result was 6,0,90                           ##
    ##  unknown            0xEF     result was 2,68,32                          ##
    ##  serial number      0xFA     same as 1A, check sensirion(says 64 bits ID)##
    ##  serial number?     0xFB     same as 1B                                  ##
    ##  device ID?         0xFF     check i2c full specs, results seems random  ##
    ############################1#################################################
    class CRCError(Exception):
        pass

    def __init__(self, addr, busnum=1):
        self.address = addr
        self.bus = SMBus(busnum)
        #self.bus.open(busnum)
        self.Reset()
        #reg = self.ReadReg()
        reg = 0
        if (reg & 0x80) and (reg & 0x01):
            self.RH_res = 11
            self.T_res = 11
        elif (reg & 0x80) and not (reg & 0x01):
            self.RH_res = 10
            self.T_res = 13
        elif not (reg & 0x80) and not (reg & 0x01):
            self.RH_res = 12
            self.T_res = 14
        else:
            self.RH_res = 8
            self.T_res = 12

    def getRH(self):
        self.bus.write_byte(self.address, self.RHmeasure_noHold)
        time.sleep(0.1)
        RH = self.bus.read_i2c_block_data(self.address, self.RH_Reg, 3)
        #print RH
        if self.CheckCRC(RH):
            self.RHum = RH
            RH[1] &= ~0x03  #reset 2 status bits(LSB)
            return -6 + 125. * (RH[0] * 256 + RH[1]) / 65536.
        else:
            #print 'CRC checksum failed, data was corrupted(RH reading)'
            #return -1
            raise self.CRCError

    def getT(self):
        self.bus.write_byte(self.address, self.Tmeasure_noHold)
        time.sleep(0.1)
        T = self.bus.read_i2c_block_data(self.address, self.T_Reg, 3)
        #print T
        if self.CheckCRC(T):
            self.Temp = T
            T[1] &= ~0x03  #reset 2 status bits(LSB)
            return -46.85 + 175.72 * (T[0] * 256 + T[1]) / 65536.
        else:
            #print 'CRC checksum failed, data was corrupted(temp reading)'
            #return -1
            raise self.CRCError

    def Reset(self):
        self.bus.write_byte(self.address, self.Soft_Reset)
        time.sleep(0.02)  #must wait 15ms

    def ReadReg(self):
        reg = self.bus.read_word_data(self.address, self.Read_Reg)
        crc = [reg & 0xFF, (reg & 0xFF00) >> 8]

        if self.CheckCRC(crc):
            return reg & 0xFF
        else:
            #print 'Error : CRC not matching !'
            #return 0
            raise self.CRCError

    def WriteReg(self, val):
        reg = self.ReadReg()
        reg &= 0x38
        self.bus.write_byte_data(self.address, self.Write_Reg, val)

    def test(self):
        self.T = []
        self.getRH()
        self.getT()
        for i in range(256):
            try:
                time.sleep(10)
                self.T.append(
                    (hex(i), self.bus.read_i2c_block_data(sensor.address, i)))
                print(hex(i), 'success reading')
            except IOError as err:
                print(hex(i), 'failed reading')
        return self.T

    def CheckCRC(self, buf):
        poly = 0x131
        crc = 0
        #print buf[2]
        for by in buf:
            crc ^= by
            for i in range(8):
                if crc & 0x80:
                    crc = (crc << 1) ^ poly
                else:
                    crc <<= 1
                #print crc
        return crc == 0
Beispiel #34
0
def parse(t):
    # 9 bits of resolution stored in 2 bytes
    r = t >> 7
    # MSB set?
    if t & 0x8000:
        # one's complement
        r = ~r & 0x1FF
        # two's complement
        r = r - 1
        # significance: means negative temp
        r = -r

    r = r / 2.0

    return r


def ctof(t):
    return ((9.0 / 5.0) * parse(t)) + 32.0


while True:
    temp = i2c1.read_word_data(addr, 0)
    tempA = temp & 0xFF
    tempB = (temp >> 8) & 0xFF
    temp = (tempA << 8) | tempB

    print "read: %04x = %.1f C (%.1f F)" % (temp, parse(temp), ctof(temp))
    time.sleep(0.5)
Beispiel #35
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)
Beispiel #36
0
class MLX90614_IR_sensor():
    '''This class will read the IR temperatue values from the sensor'''
    def __init__(self, address):
        '''Initalizing all variables 
		'''
        #address working at
        self.address = address

        #note that the default slave address is 0x00
        #TODO: how to detect several different addresses at once
        #self.address = 0x5a

        #Objec temperature address
        self.tobj_address = 0x27  #0x27

        #ambien temperature address
        self.tamb_address = 0x26  #0x26

        #smbus command setup
        self.bus = SMBus(1)

        #inital ambient and object temperatures
        self.init_tamb_value = 0.0
        self.init_tobj_value = 0.0

        #inital tamb and tobj values converted to Celsius
        self.tamb_ans = 0.0
        self.tobj_ans = 0.0

        #ambient temperature
        self.tamb_num = 0.0
        #object temperature
        self.tobj_num = 0.0

        self.tobj_percent_limit_up = 0.0
        self.tobj_percent_limit_down = 0.0
        self.tamb_percent_limit_up = 0.0
        self.tamb_percent_limit_down = 0.0

        #instantiate the config file and extract the dict
        #opening the config file
        self.config = config.config.Config()
        #reading the config file
        #self.config.readconfig()
        #extract the slice and slice values
        #print self.config.dict

        #dict length for data analysis
        self.length = int(self.config.dict['length'])
        #slice length of data analysis
        self.slice = int(self.config.dict['slice'])

        #importing the control_variable() class to obtain the jump and limit values
        self.control_class = mlx.control_variable.Control_Variable()
        self.control_class.run()

        self.tobj_jump_value = 0.0
        self.tamb_jump_value = 0.0

        self.cycle = 0
        self.counter = 0

        self.tamb_data_analysis_list = []
        self.tobj_data_analysis_list = []

        self.tobj_data_analysis_result = []
        self.tamb_data_analysis_result = []

        #this is the record_list which is the varible passed to the gui
        #note that we are initalizing all variables with 0 are the six variables are there
        #the appended list data is being stored to the log files, the gui will only show a subaspect of the data
        self.record_list = [0, 0, 0, 0, 0, 0]
        self.record_dict = {self.address: []}  #, 'cycle':self.cycle }

    def read(self):
        '''getting the values from the IR device sensor'''
        self.init_tobj_value = self.bus.read_word_data(self.address,
                                                       self.tobj_address)
        #sleep for 200 ms the time for the sensor is at least 144 ms
        time.sleep(0.2)

        self.init_tamb_value = self.bus.read_word_data(self.address,
                                                       self.tamb_address)
        #sleep for 200 ms the timer for the sensor is at least 144 ms
        time.sleep(0.2)

    def object_temp_analysis(self):
        '''this function converts the object temperature from kelvin to celsius values'''
        #converting values from long bits into degrees celsius
        #using fomula in sensor datasheet manual
        #pg ?????

        #convert temperatures from kelvin to celsius
        tobj_ans = (self.init_tobj_value * 0.02) - 273.15
        #print tobj_ans
        self.tobj_ans = tobj_ans
        #mylog2.debug('Tobj: ' + repr(tobj_ans) )

        #calculate jump value
        jump_value = tobj_ans - self.tobj_num  #- tobj_ans
        #save calculated jump value to self value
        self.tobj_jump_value = jump_value

        #print 'obj jump: ', jump_value
        mylog2.debug('obj jump value: ' + repr(jump_value))

        #comparing jump value to control jump value set by user
        if jump_value >= self.control_class.jump_value:
            #reinitalize variables
            self.tobj_num = tobj_ans
            #calculate percent limit
            self.tobj_percent_limit_up = self.tobj_num * self.control_class.limit_value
            print '*****TOBJ UP*****'
            mylog2.debug('UP VALUE-Tobj:--> ' + 'object temperature value: ' +
                         repr(self.tobj_num) + 'jump up value: ' +
                         repr(jump_value) + 'temp limit value: ' +
                         repr(self.tobj_percent_limit_up) + 'jump value: ' +
                         repr(self.control_class.jump_value))

        elif jump_value <= -(self.control_class.jump_value):
            #reinitalize variables
            self.tobj_num = tobj_ans
            #calculating percent limit
            self.tobj_percent_limit_down = self.tobj_num * self.control_class.limit_value
            print '******TOBJ DOWN*****'
            mylog2.debug('DOWN VALUE-Tobj:--> ' +
                         'object temperature value: ' + repr(self.tobj_num) +
                         'jump up value: ' + repr(jump_value) +
                         'temp limit value: ' +
                         repr(self.tobj_percent_limit_down) + 'jump value: ' +
                         repr(self.control_class.jump_value))

        else:
            print 'no change'

    def ambient_temp_analysis(self):
        '''this function records the ambient temperatuer and converts the value to degrees celsisus
		'''
        tamb_ans = (self.init_tamb_value * 0.02) - 273.15
        #print tamb_ans
        #mylog2.debug('tamb ans: ' + repr(tamb_ans) )
        self.tamb_ans = tamb_ans

        #calculate jump value
        jump_value = tamb_ans - self.tamb_num  #- tamb_ans
        #print 'amb jump: ', jump_value

        if jump_value >= self.control_class.jump_value:
            #assuming the value is +
            #reinitalize varialbes
            self.tamb_num = tamb_ans

            #calculate percent limit
            tamb_percent_limit_up = self.tamb_num * self.control_class.limit_value

            print '*********TAMB UP***********'

            mylog2.debug('UP VALUE-Tamb:-->' + 'Ambient temperature value: ' +
                         repr(self.tamb_num) + 'jump up value: ' +
                         repr(jump_value) + 'temp limit value: ' +
                         repr(self.tamb_percent_limit_up) + 'jump value: ' +
                         repr(self.control_class.jump_value))

        elif jump_value <= -(self.control_class.jump_value):
            #reinitalize variables
            self.tamb_num = tamb_ans
            #calculate percent limit
            tamb_percent_limit_down = self.tamb_num * self.control_class.limit_value

            print '*********TAMB DOWN***********'

            mylog2.debug('DOWN VALUE-Tamb' + 'Ambient temperature value: ' +
                         repr(self.tamb_num) + 'jump up value: ' +
                         repr(jump_value) + 'temp limit value: ' +
                         repr(self.tamb_percent_limit_down) + 'jump value: ' +
                         repr(self.control_class.jump_value))

        else:
            print 'no change'

    def data_analysis(self):
        '''This function does the data analysis for the data
		'''
        #appending items to list
        self.tobj_data_analysis_list.append(self.tobj_ans)  #_num)
        self.tamb_data_analysis_list.append(self.tamb_ans)  #num)

        if len(self.tobj_data_analysis_list) > self.length:  #15:
            #if the length is greater then 50
            for item in self.tobj_data_analysis_list[:self.slice]:  #10]:
                #take out the first 20 items and pop them out
                self.tobj_data_analysis_list.pop(0)

        if len(self.tamb_data_analysis_list) > self.length:  #15:
            #pop out the first 20 items in the list
            for item in self.tamb_data_analysis_list[:self.slice]:  #10]:
                self.tamb_data_analysis_list.pop(0)

        #doing tobject calculations
        tobj_min = min(self.tobj_data_analysis_list[-self.slice:])  #[-5:])
        tobj_max = max(self.tobj_data_analysis_list[-self.slice:])  #[-5:])
        tobj_sum = sum(self.tobj_data_analysis_list[-self.slice:])  #[-5:])
        tobj_len = len(
            self.tobj_data_analysis_list)  #[ -self.slice: ] ) #[-5:])
        tobj_avg = tobj_sum / tobj_len

        #doign tambient claculations
        tamb_min = min(self.tamb_data_analysis_list[-self.slice:])  #[-5:])
        tamb_max = max(self.tamb_data_analysis_list[-self.slice:])  #[-5:])
        tamb_sum = sum(self.tamb_data_analysis_list[-self.slice:])  #[-5:])
        tamb_len = len(
            self.tamb_data_analysis_list)  #[ -self.slice: ] ) #[-5:])
        tamb_avg = tamb_sum / tobj_len

        self.record_list = [
            tobj_min, tobj_max, tobj_avg, tamb_min, tamb_max, tamb_avg,
            tobj_len, tamb_len
        ]

        #logging the data
        mylog2.debug('Record list: ' + repr(self.record_list))

    def record_data(self):
        '''this function saves the data to csv files note that this data is not needed and necessary
		TODO: Deprecated function '''
        myfile = open(FILENAME, 'a')
        newrow = time.strftime('%H:%M:%S,')
        newrow += str(self.cycle) + ","
        newrow += str(self.address) + ","
        newrow += str(self.tobj_ans) + ","
        newrow += str(self.tamb_ans)
        newrow += NEWLINE
        myfile.write(newrow)
        myfile.close()

    def run(self):
        ''''Function which runs the value'''
        #runt the control class to ensure the varaibles are set right and can be changed as needed
        #self.control_class.run()
        mylog2.debug('control variable values: ' +
                     repr(self.control_class.jump_value) + "--" +
                     repr(self.control_class.limit_value))
        self.cycle += 1
        print

        print 'Time: ', time.strftime('%H:%M:%S,')
        print 'cycle: ', self.cycle

        self.read()
        self.object_temp_analysis()
        self.ambient_temp_analysis()
        self.data_analysis()
        self.record_data()

        print 'Address: %s -- tobject: %s -- tambient: %s' % (
            self.address, self.tobj_num, self.tamb_num)

        #log the results
        mylog2.debug('tamb data analysis: ' +
                     repr(self.tamb_data_analysis_result))
class PiPuckMotorServer(object):
    """ROS Node to expose topics relating to the Pi-puck motors."""
    def __init__(self):
        """Initialise node."""
        self._bus = SMBus(I2C_CHANNEL)

        rospy.on_shutdown(self.close_bus)

        self._steps_right_pub = rospy.Publisher('motors/steps_right',
                                                UInt16,
                                                queue_size=10)
        self._steps_left_pub = rospy.Publisher('motors/steps_left',
                                               UInt16,
                                               queue_size=10)
        self._real_steps_right_pub = rospy.Publisher('motors/real_steps_right',
                                                     Int64,
                                                     queue_size=10)
        self._real_steps_left_pub = rospy.Publisher('motors/real_steps_left',
                                                    Int64,
                                                    queue_size=10)
        self._odometry_pub = rospy.Publisher('motors/odometry',
                                             Odometry,
                                             queue_size=10)

        rospy.init_node("motors")

        rospy.Subscriber("motors/speed_right", Float32, self.callback_right)
        rospy.Subscriber("motors/speed_left", Float32, self.callback_left)

        self._rate = rospy.Rate(rospy.get_param('~rate', 10))

        tf_prefix_key = rospy.search_param("tf_prefix")
        if tf_prefix_key:
            tf_prefix = rospy.get_param(tf_prefix_key, None)
        else:
            tf_prefix = None
        if tf_prefix is not None and not tf_prefix.endswith("/"):
            tf_prefix += "/"

        self._reference_frame = REFERENCE_FRAME_ID
        if tf_prefix:
            self._reference_frame = tf_prefix + self._reference_frame

        self._left_overflows = 0
        self._right_overflows = 0

        self._left_steps_previous = 0
        self._right_steps_previous = 0
        self._real_left_steps_previous = 0
        self._real_right_steps_previous = 0

        self._left_motor_speed = 0
        self._right_motor_speed = 0

        self._estimate_x = 0
        self._estimate_y = 0
        self._estimate_theta = 0

        self._last_measurement_time = rospy.get_time()

    @staticmethod
    def convert_speed(speed):
        """Convert input speed data into a speed value for the stepper motors."""
        speed = float(speed)
        if speed > 1.0:
            speed = 1.0
        elif speed < -1.0:
            speed = -1.0
        return int(speed * MAX_SPEED)

    def callback_left(self, data):
        """Handle requests for speed change of left motor."""
        self._left_motor_speed = data.data
        self._bus.write_word_data(
            EPUCK_I2C_ADDR, LEFT_MOTOR_SPEED,
            PiPuckMotorServer.convert_speed(self._left_motor_speed))

    def callback_right(self, data):
        """Handle request for speed change of right motor."""
        self._right_motor_speed = data.data
        self._bus.write_word_data(
            EPUCK_I2C_ADDR, RIGHT_MOTOR_SPEED,
            PiPuckMotorServer.convert_speed(self._right_motor_speed))

    def close_bus(self):
        """Close the I2C bus after the ROS Node is shutdown."""
        self._bus.write_word_data(EPUCK_I2C_ADDR, LEFT_MOTOR_SPEED, 0)
        self._bus.write_word_data(EPUCK_I2C_ADDR, RIGHT_MOTOR_SPEED, 0)
        self._bus.close()

    @staticmethod
    def euler_to_quaternion(yaw, pitch, roll):
        """Convert euler angles of pitch, roll, and yaw to a quaternion.

        Based on code from
        https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles.

        We don't use tf.transforms here to reduce dependence on tf and increase performance on this
        simple task.
        """
        c_y = cos(yaw * 0.5)
        s_y = sin(yaw * 0.5)
        c_p = cos(pitch * 0.5)
        s_p = sin(pitch * 0.5)
        c_r = cos(roll * 0.5)
        s_r = sin(roll * 0.5)

        q_w = c_y * c_p * c_r + s_y * s_p * s_r
        q_x = c_y * c_p * s_r - s_y * s_p * c_r
        q_y = s_y * c_p * s_r + c_y * s_p * c_r
        q_z = s_y * c_p * c_r - c_y * s_p * s_r

        return Quaternion(x=q_x, y=q_y, z=q_z, w=q_w)

    def run(self):
        """ROS Node server."""
        initial_left_steps = int(
            self._bus.read_word_data(EPUCK_I2C_ADDR, LEFT_MOTOR_STEPS))
        initial_right_steps = int(
            self._bus.read_word_data(EPUCK_I2C_ADDR, RIGHT_MOTOR_STEPS))

        # Initial steps are set to counter the fact that the node may have previously run and the
        # e-puck firmware will not necessarily have been reset.
        self._left_steps_previous = initial_left_steps
        self._right_steps_previous = initial_right_steps
        self._real_left_steps_previous = initial_left_steps
        self._real_right_steps_previous = initial_right_steps

        while not rospy.is_shutdown():
            # Get current steps
            left_steps = int(
                self._bus.read_word_data(EPUCK_I2C_ADDR, LEFT_MOTOR_STEPS))
            right_steps = int(
                self._bus.read_word_data(EPUCK_I2C_ADDR, RIGHT_MOTOR_STEPS))

            # Get step measurement time
            measurement_time = rospy.get_time()

            # Check for overflows and underflows
            if left_steps + (MAX_MOTOR_STEPS_RAW /
                             2.0) < self._left_steps_previous:
                self._left_overflows += 1
            elif left_steps > self._left_steps_previous + (
                    MAX_MOTOR_STEPS_RAW / 2.0):
                self._left_overflows -= 1

            if right_steps + (MAX_MOTOR_STEPS_RAW /
                              2.0) < self._right_steps_previous:
                self._right_overflows += 1
            elif right_steps > self._right_steps_previous + (
                    MAX_MOTOR_STEPS_RAW / 2.0):
                self._right_overflows -= 1

            # Calculate the real steps left and right accounting for overflows
            real_left_steps = left_steps + self._left_overflows * MAX_MOTOR_STEPS_RAW
            real_right_steps = right_steps + self._right_overflows * MAX_MOTOR_STEPS_RAW

            # Publish raw and real steps
            self._steps_right_pub.publish(right_steps)
            self._steps_left_pub.publish(left_steps)
            self._real_steps_right_pub.publish(real_right_steps)
            self._real_steps_left_pub.publish(real_left_steps)

            # Calculate step changes
            delta_left = (real_left_steps -
                          self._real_left_steps_previous) * MOTOR_STEP_DISTANCE
            delta_right = (real_right_steps - self._real_right_steps_previous
                           ) * MOTOR_STEP_DISTANCE

            #Calculate delta steps and turn
            delta_theta = (delta_right - delta_left) / WHEEL_DISTANCE
            delta_steps = (delta_right + delta_left) / 2.0

            # Update the estimate for x, y, and rotation
            self._estimate_x += delta_steps * cos(self._estimate_theta +
                                                  delta_theta / 2.0)
            self._estimate_y += delta_steps * sin(self._estimate_theta +
                                                  delta_theta / 2.0)
            self._estimate_theta += delta_theta

            # Update previous steps to current
            self._left_steps_previous = left_steps
            self._right_steps_previous = right_steps
            self._real_left_steps_previous = real_left_steps
            self._real_right_steps_previous = real_right_steps

            # Send odometry
            odometry_message = Odometry()

            odometry_message.pose.pose.orientation = PiPuckMotorServer.euler_to_quaternion(
                self._estimate_theta, 0, 0)
            odometry_message.pose.pose.position.x = self._estimate_x
            odometry_message.pose.pose.position.y = self._estimate_y

            odometry_message.twist.twist.linear.x = delta_steps / (
                measurement_time - self._last_measurement_time)
            odometry_message.twist.twist.angular.z = delta_theta / (
                measurement_time - self._last_measurement_time)

            odometry_message.header.frame_id = self._reference_frame

            self._odometry_pub.publish(odometry_message)

            self._last_measurement_time = measurement_time

            self._rate.sleep()
Beispiel #38
0
class SRF02:
    def __init__(self):

        self._i2c = SMBus(1)
        self._i2c_address = SRF02_I2C_ADDRESS
        self._waiting_for_echo = False

        yesterday = datetime.now() - timedelta(1)
        self._time_last_burst = yesterday

        # The last distance measurement
        self.distance = None  # meters

        # On power up, the detection threshold is set to 28cm (11")
        self.mindistance = 0.28  # meters

        # This is mostly for debugging and testing
        self.num_bursts_sent = 0

        # check that the sensor is present - read the version
        self.version = self._read_version()
        log.info("SRF-02 Ultrasonic Sensor initialized. Version: %d" % self.version)

        # we want to check how often we get exceptions
        self.error_counter = 0

    # Should be called in some sensor loop, maybe at 100Hz. Is fast.
    # Will trigger an ultrasonic burst or check if we received an echo.
    # I we have a measurement, it is returned in meters.
    def update(self):

        distance = None

        now = datetime.now()
        time_since_last_burst = (now - self._time_last_burst).total_seconds()

        #        log.debug("time since last burst: {}".format(time_since_last_burst))

        if self._waiting_for_echo:
            # make sure we wait at least some amount of time before we read
            if time_since_last_burst > SRF02_MIN_TIME_BETWEEN_BURST_READ:
                # check if we have an echo
                distance = self._read_echo()

            # Fallback if we don't get an echo, just stop waiting
            # from the data sheet:
            # The SRF02 will always be ready 70mS after initiating the ranging.
            if distance is None and time_since_last_burst > SRF02_MAX_WAIT_TIME:
                log.warn("Fallback! Waited longer than 70ms!")
                self._waiting_for_echo = False

        if (not self._waiting_for_echo) and time_since_last_burst > SRF02_MIN_TIME_BETWEEN_BURSTS:
            self._send_burst()

        expected_error = self._calc_expected_error(distance)

        return distance, expected_error

    def _send_burst(self):
        self._i2c.write_byte_data(self._i2c_address, 0, 0x51)
        self._waiting_for_echo = True
        self._time_last_burst = datetime.now()
        self.num_bursts_sent += 1
        log.debug("Burst sent.")

    def _read_echo(self):
        # it must be possible to read all of these data in 1 i2c transaction
        # buf[0] software version. If this is 255, then the ping has not yet returned
        # buf[1] unused
        # buf[2] high byte range
        # buf[3] low byte range
        # buf[4] high byte minimum auto tuned range
        # buf[5] low byte minimum auto tuned range

        # We use the version information to detect if the result is there yet.
        # 255 is a dummy version for the case that no echo has been received yet. For me, the real version is "6".
        if self._read_version() == 255:
            log.debug("Version is 255")
            return None

        self.distance = self._i2c.read_word_data(self._i2c_address, 2) / 255
        self.mindistance = self._i2c.read_word_data(self._i2c_address, 4) / 255

        # A value of 0 indicates that no objects were detected. We prefer None to represent this.
        if self.distance == 0:
            self.distance = None

        self._waiting_for_echo = False
        log.debug("echo received! distance is: {}".format(self.distance))

        return self.distance

    # The version can be read from register 0.
    # Reading it has no real value for us, but we can use it to determine if a measurement is finished or not.
    def _read_version(self):
        try:
            return self._i2c.read_byte_data(self._i2c_address, 0)

            # 255 means that the unit is still measuring the distance
        except IOError:
            log.error("Recovering from IOError")
            self.error_counter += 1
            return 255

    # find out what kind of error we expect (used in sensor fusion)
    def _calc_expected_error(self, distance):

        # no reading at all
        if distance is None:
            return SENSOR_ERROR_MAX

        # object too close
        if distance <= self.mindistance:
            return SRF02_SENSOR_ERROR_LOW_RANGE

        # good distance, nice measurement
        elif distance <= SRF02_MAX_RANGE:
            return SRF02_SENSOR_ERROR_GOOD_RANGE

        # object too far
        else:
Beispiel #39
0
 def getTempurature(self):
     bus = SMBus(1)
     self.tempurature = self.decodePMBus(
         bus.read_word_data(self.address, 0x8D))
     bus.close()
     return self.tempurature
class templogger():
	_cal_AC1 = 0
	_cal_AC2 = 0
	_cal_AC3 = 0
	_cal_AC4 = 0
	_cal_AC5 = 0
	_cal_AC6 = 0
	_cal_B1 = 0
	_cal_B2 = 0
	_cal_MB = 0
	_cal_MC = 0
	_cal_MD = 0
	bmp180 = 0
	bh1750 = 0
	lm75addr = 0
	i2c1 = 0
	db = 0
	api = 0
	feed = 0
	tempds = 0
	lightds = 0
	pressds = 0
		

	def __init__(self, filename):
		self.lm75addr = 0x4f
		self.db = sqlite3.connect(filename)
		self.db.execute("CREATE TABLE IF NOT EXISTS temp_series(date datetime, event TEXT, value REAL, detail TEXT)")	
		self.db.commit()
		self.bmp180 = 0x77
		self.bh1750 = 0x23
		self.i2c1 = SMBus(1)
		self.calibration()
		#self.api = xively.XivelyAPIClient(api_key)
		#self.feed = self.api.feeds.get(feed_id)
		#self.tempds = self.get_datastream(self.feed, "Temperature")
		#self.lightds = self.get_datastream(self.feed, "Light")
		#self.pressds = self.get_datastream(self.feed, "Pressure")		

	def get_datastream(self, feed, name):
		try:
			datastream = feed.datastreams.get(name)
			return datastream
		except:
			datastream = feed.datastreams.create(name, tags="")
			return datastream

	def publish(self, datastream, value, time):
		datastream.current_value = value
		datastream.at = time
		try:
			datastream.update()
		except requests.HTTPError as e:
			print "HTTPError({0}): {1}".format(e.errno, e.strerror)
		
	def calibration(self):
		self._cal_AC1 = self.read_16bit_regs(self.bmp180, 0xaa)
		self._cal_AC2 = self.read_16bit_regs(self.bmp180, 0xac)
		self._cal_AC3 = self.read_16bit_regs(self.bmp180, 0xae)
		self._cal_AC4 = self.read_16bit_regu(self.bmp180, 0xb0)
		self._cal_AC5 = self.read_16bit_regu(self.bmp180, 0xb2)
		self._cal_AC6 = self.read_16bit_regu(self.bmp180, 0xb4)
		self._cal_B1 = self.read_16bit_regs(self.bmp180, 0xb6)
		self._cal_B2 = self.read_16bit_regs(self.bmp180, 0xb8)
		self._cal_MB = self.read_16bit_regs(self.bmp180, 0xba)
		self._cal_MC = self.read_16bit_regs(self.bmp180, 0xbc)
		self._cal_MD = self.read_16bit_regs(self.bmp180, 0xbe)

	def readRawTemp(self):
		self.i2c1.write_byte_data(self.bmp180, 0xf4, 0x2e)
		time.sleep(0.005)
		raw = self.read_16bit_regu(self.bmp180, 0xf6)
		return raw

	def readTemperature(self):
		ut = self.readRawTemp()
		x1 = ((ut - self._cal_AC6) * self._cal_AC5) >> 15
		x2 = (self._cal_MC << 11) / (x1 + self._cal_MD)
		b5 = x1 + x2
		temp = ((b5 + 8) >> 4)/10.0
		return temp
	
	def readRawPressure(self):
		self.i2c1.write_byte_data(self.bmp180, 0xf4, 0xf4) #Read ultra high resolution
		time.sleep(0.026)
		msb = self.i2c1.read_byte_data(self.bmp180, 0xf6)
		lsb = self.i2c1.read_byte_data(self.bmp180, 0xf7)
		xlsb = self.i2c1.read_byte_data(self.bmp180, 0xf8)
		raw = (msb << 16) + (lsb << 8) + (xlsb) >> 5
		return raw
	
	def readPressure(self):
		# Get raw temperature and pressure
		ut = self.readRawTemp()
		up = self.readRawPressure()
		# Convert to actual compensated and calibrated pressure (see Datasheet)
		x1 = ((ut - self._cal_AC6) * self._cal_AC5) >> 15
		x2 = (self._cal_MC << 11) / (x1 + self._cal_MD)
		b5 = x1 + x2
		b6 = b5 - 4000
		x1 = (self._cal_B2 * (b6 * b6) >> 12) >> 11
		x2 = (self._cal_AC2 * b6) >> 11
		x3 = x1 + x2
		b3 = (((self._cal_AC1 * 4 + x3) << 3) + 2) / 4
	
		x1 = (self._cal_AC3 * b6) >> 13
		x2 = (self._cal_B1 * ((b6 * b6) >> 12)) >> 16
		x3 = ((x1 + x2) + 2) >> 2
		b4 = (self._cal_AC4 * (x3 + 32768)) >> 15
		b7 = (up - b3) * (50000 >> 3)
	
		if (b7 < 0x80000000):
			p = (b7 * 2) / b4
		else:
			p = (b7 / b4) * 2
		x1 = (p >> 8) * (p >> 8)
		x1 = (x1 * 3038) >> 16
		x2 = (-7357 * p) >> 16
		p = p + ((x1 + x2 + 3791) >> 4)
		return p

	def readLM75Temperature(self):
		# Measure temperature
		temp = self.i2c1.read_word_data(self.lm75addr,0)
		# Swap lower and higher byte
		temp = (((temp & 0xff) << 8)|((temp >> 8) & 0xff))
		value = temp >> 5
		# Make signed integer
		if (temp & 0x8000):
			# one's complement
			value = (~value & 0x1FF)
			# two's complement
			value = value - 1
			# significance: means negative temp
			value = -value
		value = value / 8.0
		return value

	def readBH1750Light(self):
		# Measure light
		luxtmp = self.i2c1.read_word_data(self.bh1750, 0x10)
		# Convert to actual lux (see Datasheet)
		lux = (((luxtmp >> 8) & 0xff) | ((luxtmp & 0xff) << 8))/1.2
		return lux

	def measure(self):
		thisdate = datetime.datetime.utcnow()
		nu = datetime.datetime.utcnow()
		print(thisdate)
		value = self.readLM75Temperature()
		#self.publish(self.tempds, value, nu)
		self.db.execute(
		'INSERT INTO temp_series(date, event, value, detail) VALUES(?,?,?,?)',
		(
			thisdate,
			"Temperature",
			value,
			"Green House"
		)
		)
		self.db.commit()
		lux = self.readBH1750Light()
		#self.publish(self.lightds, lux, nu)
		self.db.execute(
		'INSERT INTO temp_series(date, event, value, detail) VALUES(?, ?, ?, ?)',
		(
			thisdate,
			"Light intensity",
			lux,
			"Greenhouse"
		)
		)
		self.db.commit()
		pressure = self.readPressure()
		#self.publish(self.pressds, pressure, nu)
		self.db.execute(
		'INSERT INTO temp_series(date, event, value, detail) VALUES(?, ?, ?, ?)',
		(
			thisdate,
			"Pressure",
			pressure,
			"Greenhouse"
		)
		)
		self.db.commit()

	def print_climate(self):
		print "The temperature is: %i Degrees Celsius" % (self.readLM75Temperature())
		print "The light intensity is: %i Lux" % (self.readBH1750Light())
		print "The pressure is: %i Pascal" % (self.readPressure())		
	
	def read_16bit_regu(self, address, register):
		a = self.i2c1.read_byte_data(address, register)
		b = self.i2c1.read_byte_data(address, register+1)
		return ((a << 8) | b)

	def read_16bit_regs(self, address, register):
		a = self.i2c1.read_byte_data(address, register)
		b = self.i2c1.read_byte_data(address, register+1)
		c = (a << 8)|b
		if (c & 0x8000):
			c = (~c & 0xffff)
			c = c-1
			c = -c
		return c	
Beispiel #41
0
class I2CDevice(object):
    """
    Class for communicating with an I2C device.

    Allows reading and writing 8-bit, 16-bit, and byte array values to
    registers on the device.

    It can handle signed, unsigned and endianness.

    :var uint address: Assigned I2C address.
    :var uint8 busid: Assigned IC2 bus identifier.

    :param uint address: I2C address.
    :param uint busid: IC2 bus identifier.
    :param class i2c_class: Class implementing the I2C reading interface.
     If None, smbus.SMBus will be used.
    """

    def __init__(self, busnum, address, i2c_class=None):
        self._busnum = busnum
        self._address = address

        if i2c_class is None:
            from smbus import SMBus
            self._bus = SMBus(busnum)
        else:
            self._bus = i2c_class(busnum)

        self._logger = logging.getLogger(
            '/dev/i2c-{}/{:#x}'.format(busnum, address)
        )

    def _debug(self):
        self._logger.setLevel(logging.DEBUG)
        self._logger.addHandler(logging.StreamHandler())

    @property
    def busnum(self):
        return self._busnum

    @property
    def address(self):
        return self._address

    def write(self, value):
        """
        Write the specified 8-bit value to the device base address.
        """
        assert bound_bits(value, 8)

        self._bus.write_byte(self._address, value)
        self._logger.debug(
            'Wrote value {:#x}'.format(value)
        )

    def register_write_u8(self, register, value):
        """
        Write an 8-bit value to the specified 8-bit register.
        """
        assert bound_bits(register, 8)
        assert bound_bits(value, 8)

        self._bus.write_byte_data(self._address, register, value)
        self._logger.debug(
            'Wrote to register {:#x} value {:#x}'.format(register, value)
        )

    def register_write_u16(self, register, value):
        assert bound_bits(register, 8)
        assert bound_bits(value, 16)

        self._bus.write_word_data(self._address, register, value)
        self._logger.debug(
            'Wrote to register pair {:#x}, {:#x} value {:#x} '.format(
                register, register + 1, value
            )
        )

    def read(self):
        """
        Read the device base address and return a 8-bit value.
        """
        result = self._bus.read_byte(self._address) & 0xFF
        self._logger.debug(
            'Read value {:#x}'.format(result)
        )
        return result

    def register_read_u8(self, register):
        """
        Read the specified 8-bit register and return a 8-bit value.
        """
        assert bound_bits(register, 8)

        result = self._bus.read_byte_data(self._address, register) & 0xFF
        self._logger.debug(
            'Read from register {:#x} returns {:#x}'.format(register, result)
        )

        return result

    def register_read_s8(self, register):
        """
        Read the specified 8-bit register and return a signed 7-bit value.
        """
        result = self.register_read_u8(register)
        if result > 127:
            result -= 256
            self._logger.debug('... as signed: {:#x}'.format(result))
        return result

    def register_read_u16(self, register, little_endian=True):
        """
        Read the specified 8-bit register and return a 16-bit value with the
        specified endianness.

        Default is little endian, or least significant byte first.
        """
        assert bound_bits(register, 8)

        result = self._bus.read_word_data(self._address, register) & 0xFFFF
        self._logger.debug(
            'Read from register pair {:#x}, {:#x} value {:#x} '.format(
                register, register + 1, result
            )
        )

        # 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)
            self._logger.debug('... as big endian: {:#x}'.format(result))
        return result

    def register_read_s16(self, register, little_endian=True):
        """
        Read the specified 8-bit register and return a signed 15-bit value
        with the specified endianness.

        Default is little endian, or least significant byte first.
        """
        result = self.register_read_u16(register, little_endian)
        if result > 32767:
            result -= 65536
            self._logger.debug('... as signed: {:#x}'.format(result))
        return result

    def register_read_u16le(self, register):
        """
        Same as register_read_u16 with endianness set to little endian.
        """
        return self.register_read_u16(register, little_endian=True)

    def register_read_u16be(self, register):
        """
        Same as register_read_u16 with endianness set to big endian.
        """
        return self.register_read_u16(register, little_endian=False)

    def register_read_s16le(self, register):
        """
        Same as register_read_s16 with endianness set to little endian.
        """
        return self.register_read_s16(register, little_endian=True)

    def register_read_s16be(self, register):
        """
        Same as register_read_s16 with endianness set to big endian.
        """
        return self.register_read_s16(register, little_endian=False)
Beispiel #42
0
    class LinuxI2cBus:
        """A Linux I²C device, which is itself an I²C bus.

        Should not be instantiated directly; use `LinuxI2c.find_devices`
        instead.

        This type mimics the `smbus.SMBus` read/write/close APIs.  However,
        `open` does not take any parameters, and not all APIs are available.
        """

        # note: this is not a liquidctl BaseBus, as that would cause
        # find_liquidctl_devices to try to directly instantiate it

        def __init__(self, i2c_dev):
            self._i2c_dev = i2c_dev
            self._smbus = None

            try:
                assert i2c_dev.name.startswith('i2c-')
                self._number = int(i2c_dev.name[4:])
            except:
                raise ValueError(f'cannot infer bus number')

        def find_devices(self, drivers, **kwargs):
            """Probe drivers and find compatible devices in this bus."""
            for drv in drivers:
                yield from drv.probe(self, **kwargs)

        def open(self):
            """Open the I²C bus."""
            if not self._smbus:
                try:
                    self._smbus = SMBus(self._number)
                except FileNotFoundError:
                    if Path('/sys/class/i2c-dev').exists():
                        raise
                    raise OSError('kernel module i2c-dev not loaded') from None

        def read_byte(self, address):
            """Read a single byte from a device."""
            value = self._smbus.read_byte(address)
            _LOGGER.debug('read byte @ 0x%02x: 0x%02x', address, value)
            return value

        def read_byte_data(self, address, register):
            """Read a single byte from a designated register."""
            value = self._smbus.read_byte_data(address, register)
            _LOGGER.debug('read byte data @ 0x%02x:0x%02x: 0x%02x', address,
                          register, value)
            return value

        def read_word_data(self, address, register):
            """Read a single 2-byte word from a given register."""
            value = self._smbus.read_word_data(address, register)
            _LOGGER.debug('read word data @ 0x%02x:0x%02x: 0x%04x', address,
                          register, value)
            return value

        def read_block_data(self, address, register):
            """Read a block of up to  32 bytes from a given register."""
            data = self._smbus.read_block_data(address, register)
            _LOGGER.debug('read block data @ 0x%02x:0x%02x: %r', address,
                          register, LazyHexRepr(data))
            return data

        def write_byte(self, address, value):
            """Write a single byte to a device."""
            _LOGGER.debug('writing byte @ 0x%02x: 0x%02x', address, value)
            return self._smbus.write_byte(address, value)

        def write_byte_data(self, address, register, value):
            """Write a single byte to a designated register."""
            _LOGGER.debug('writing byte data @ 0x%02x:0x%02x: 0x%02x', address,
                          register, value)
            return self._smbus.write_byte_data(address, register, value)

        def write_word_data(self, address, register, value):
            """Write a single 2-byte word to a designated register."""
            _LOGGER.debug('writing word data @ 0x%02x:0x%02x: 0x%04x', address,
                          register, value)
            return self._smbus.write_word_data(address, register, value)

        def write_block_data(self, address, register, data):
            """Write a block of byte data to a given register."""
            _LOGGER.debug('writing block data @ 0x%02x:0x%02x: %r', address,
                          register, LazyHexRepr(data))
            return self._smbus.write_block_data(address, register, data)

        def close(self):
            """Close the I²C connection."""
            if self._smbus:
                self._smbus.close()
                self._smbus = None

        def load_eeprom(self, address):
            """Return EEPROM name and data in `address`, or None if N/A."""

            # uses kernel facilities to avoid directly reading from the EEPROM
            # or managing its pages, also avoiding the need for unsafe=smbus

            dev = f'{self._number}-{address:04x}'
            try:
                name = self._i2c_dev.joinpath(dev, 'name').read_text().strip()
                eeprom = self._i2c_dev.joinpath(dev, 'eeprom').read_bytes()
                return LinuxEeprom(name, eeprom)
            except Exception as err:
                return None

        @property
        def name(self):
            return self._i2c_dev.name

        @property
        def description(self):
            return self._try_sysfs_read('name')

        @property
        def parent_vendor(self):
            return self._try_sysfs_read_hex('device/vendor')

        @property
        def parent_device(self):
            return self._try_sysfs_read_hex('device/device')

        @property
        def parent_subsystem_vendor(self):
            return self._try_sysfs_read_hex('device/subsystem_vendor')

        @property
        def parent_subsystem_device(self):
            return self._try_sysfs_read_hex('device/subsystem_device')

        @property
        def parent_driver(self):
            try:
                return Path(
                    os.readlink(self._i2c_dev.joinpath('device/driver'))).name
            except FileNotFoundError:
                return None

        def __str__(self):
            if self.description:
                return f'{self.name}: {self.description}'
            return self.name

        def __repr__(self):
            def hexid(maybe):
                if maybe is not None:
                    return f'{maybe:#06x}'
                return 'None'

            return f'{self.__class__.__name__}: name: {self.name!r}, ' \
                   f'description: {self.description!r}, ' \
                   f'parent_vendor: {hexid(self.parent_vendor)}, ' \
                   f'parent_device: {hexid(self.parent_device)}, ' \
                   f'parent_subsystem_vendor: {hexid(self.parent_subsystem_vendor)}, ' \
                   f'parent_subsystem_device: {hexid(self.parent_subsystem_device)}, ' \
                   f'parent_driver: {self.parent_driver!r}'

        def _try_sysfs_read(self, *sub, default=None):
            try:
                return self._i2c_dev.joinpath(*sub).read_text().rstrip()
            except FileNotFoundError:
                return default

        def _try_sysfs_read_hex(self, *sub, default=None):
            try:
                return int(self._i2c_dev.joinpath(*sub).read_text(), base=16)
            except FileNotFoundError:
                return default
Beispiel #43
0
class I2CBus:

    # The device ids supported
    # Note: Under linux, the enumeration of the i2c devices is not guaranteed to match the BBB device id, i.e., i2c0 may
    # not map to /dev/i2c-0.  Here is a link on this topic: https://datko.net/2013/11/03/bbb_i2c
    # What is important from a software perspective is that pins and the device id match since we don't use the linux
    # device name.  That is, we need to use an id, 0, 1, 2, which corresponds to a specific device connected on specific
    # pins.
    # Note: I2C device 0 is not enabled by default.  There is a way to enable it (see above) but there are also possible
    # conflicts with existing capes.
    DEV_I2C_0 = 0
    DEV_I2C_1 = 1
    DEV_I2C_2 = 2

    # The following formatting is taken from struct and maps the character designations to number of bytes in the type
    __TYPE_SIZES = {'d': 8, # double - 8 bytes
                    'f': 4, # float - 4 bytes
                    'L': 4, # uint32 - 4 bytes
                    'l': 4, # int32 - 4 bytes
                    'H': 2, # uint16 - 2 bytes
                    'h': 2, # int16 - 2 bytes
                    'B': 1, # uint8 - 1 byte
                    'b': 1  # int8 - 1 byte
                   }

    def __init__(self, device):
        try:
            self._smbus = SMBus(device)
        except RuntimeError:
            raise I2CBusError("Unable to open SMBus using {}".format(device))

    def _read_multiple_bytes(self, address, offset, num_bytes):
        return self._smbus.read_i2c_block_data(address, offset, num_bytes)

    def _write_multiple_bytes(self, address, offset, byte_values):
        self._smbus.write_i2c_block_data(address, offset, list(byte_values))

    def WriteUint8(self, address, offset, value):
        self._smbus.write_byte_data(address, offset, value)

    def WriteUint16(self, address, offset, value):
        self._smbus.write_word_data(address, offset, value)
  
    def WriteInt16(self, address, offset, value):
        self._smbus.write_word_data(address, offset, value)

    def WriteUint32(self, address, offset, value):
        bytes = bytearray(struct.pack('L', value))
        self._write_multiple_bytes(address, offset, bytes)

    def WriteFloat(self, address, offset, value):
        bytes = bytearray(struct.pack('f',value))
        self._write_multiple_bytes(address, offset, bytes)

    def WriteArray(self, address, offset, values, type, endian=sys.byteorder):
        # Convert each value to its byte representation and place into a bytearray before writing to the bus
        # Note: struct.pack returns a string representation of the value.  For a 1-byte value, it is a
        # string representation of 1 byte, for a 2 or 4 byte value, it is a 2-byte of 4-byte representation
        # Therefore, it is necessary to concatentate the strings before converting to a bytearray

        if endian == 'little':
            format = '<'+type
        else:
            format = '>'+type

        byte_values = ''
        for value in values:
            byte_values += struct.pack(format, value)
        self._write_multiple_bytes(address, offset, bytearray(byte_values))

    def ReadUint8(self, address, offset):
        return self._smbus.read_byte_data(address, offset)

    def ReadUint16(self, address, offset):
        return self._smbus.read_word_data(address, offset)

    def ReadInt16(self, address, offset):
        return self._smbus.read_word_data(address, offset)

    def ReadUint32(self, address, offset):
        bytes = self._read_multiple_bytes(address, offset, I2CBus.__TYPE_SIZES['L'])
        return struct.unpack('L', str(bytearray(bytes)))[0]

    def ReadInt32(self, address, offset):
        bytes = self._read_multiple_bytes(address, offset, I2CBus.__TYPE_SIZES['l'])
        return struct.unpack('l', str(bytearray(bytes)))[0]

    def ReadFloat(self, address, offset):
        values = self._read_multiple_bytes(address, offset, I2CBus.__TYPE_SIZES['f'])
        return struct.unpack('f', str(bytearray(values)))[0]

    def ReadArray(self, address, offset, num_values, type, endian=sys.byteorder):
        # Create a format specifier based on the number of values requested.  
        # All of the values will be read as the same type, e.g., all floats, all long, etc
        # The format specifies the number of float values to convert
        format = '%s%s' % (num_values, type)
        
        # Calculate number of bytes to read
        #   - num_values is the number of values to read
        #   - num_bytes is num_values * size of each value
        num_bytes = num_values * I2CBus.__TYPE_SIZES[type]
        
        # It turns out that reading i2c block data is not supported on all Raspberry Pi's (probably a OS/driver difference)
        # The Pi 2 running Jessie doesn't support i2c (i2cget with no arguments shows no 'i' option)
        # The Pi 3 running Jessie does support i2c (i2cget with no argument shows 'i' option)
        # So, we need to support both options
        bytes = self._read_multiple_bytes(address, offset, num_bytes)

        # Match the endianess of the request.  Default is platform endianess
        # struct provides a format specifier for endianess
        if endian == 'little':
            format = '<'+format
        else:
            format = '>'+format

        return list(struct.unpack(format, str(bytearray(bytes))))