Exemplo n.º 1
7
Arquivo: i2c.py Projeto: jcollie/rpiwr
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
Exemplo n.º 2
1
class I2C(_Bus,NET):
    "Class representing a I2C bus, locally or over TCP/IP. Use an Instance of this class as the bus parameter for any board"
    Devices = {}
    DeviceList= {}
    class Device():
        """class respresening a device connected to the bus,
        instances are created automatically"""
        def __init__(self,address,InUseBy=None,Bus = None,Ident=''):
            """address = int (0x00-0xFF), address of this device
            Ident   = The Identification of the device for scan matching, default:''
            InUseBy = If an Instance of a device-class is created, InUseBy points to that Instance"""
            self.Ident = Ident
            self.InUseBy = InUseBy
            VersionStrip =Ident.split(' ')[0].lower()
            if Ident !='' and VersionStrip in I2C.DeviceList:
                self.InUseBy = I2C.DeviceList[VersionStrip](Bus,address)
            else:
                self.Type=None
            if self.InUseBy!=None:
                self.InUseBy.Ident=VersionStrip

    def __init__(self,device=0,Port=None,Server=None):
        """
        @param device The I2C bus to use e.g. /dev/i2c-0, /dev/i2c-1 etc.
        @param Port Default=None if set to an Integer this will be the TCP/IP port to listen on.
        @param Server Default=None if set to a string e.g. '192.168.200.137' the bus listening on that address/port combination will be connected to.
        @todo Ckeck for Raspberry Pi, and its version in /Proc/CPUInfo
        """
        self.Port = Port
        self.Server=Server
        if self.Server != None:  # TCP Client mode
            self.NetInit()
            self.Transaction=self._NetTransaction
        else:
            try:
                self.I2cBus = SMBus(device)
            except :
                print 'Need python-smbus for I2C bus to work'
                print ''
                print 'To install: sudo apt-get install python-smbus'
                return None
            if self.Port != None: #TCP Server Mode
                self.ServerThread = threading.Thread(target=self.ListenerTread)
                self.ServerThread.start()

    def Close(self):
        self.I2cBus.close()

    def Transaction(self, OutBuffer,read=0):
        if read!=0:
            try:
                return 0,'  '+''.join([chr(m) for m in self.I2cBus.read_i2c_block_data((ord(OutBuffer[0])>>1),ord(OutBuffer[1]))])
            except IOError:
                return 0,"  "
        else:
            self.I2cBus.write_i2c_block_data(ord(OutBuffer[0])>>1  ,ord(OutBuffer[1]), [ord(m) for m in OutBuffer[2:]])           
            return 0,None

    #
    # TODO: change Transaction to _Bus.Read_String
    #
    def scan(self,Display=None,line=0):
        for i in range(0x00,0xFF,0x02):
            ret, buf = self.Transaction(chr(i)+chr(Ident),0x20)

            Identification =""
            for c in buf[2:]:
                if ord(c)==0: break
                if ord(c) in range(32,127):
                    Identification +=c

            if Identification != "":
                if i in self.Devices:
                    self.Devices[i].Ident=Identification
                else:
                    self.Devices[i]=I2C.Device(i,Ident=Identification,Bus=self)
            if Display!=None:
                ProgressBar(i,minval=0, maxval=0xFF , Display = Display, y=line)
                sleep(.05)

    def AddDevice(self,Address, InUseBy):
        self.Devices[Address]=I2C.Device(Address,InUseBy=InUseBy,Bus=self)
Exemplo n.º 3
0
class LEDSign:
    def __init__(self):
        self.s = SMBus(0)
        self.lock = Lock()

    def print_message(self, line, message):
        if len(message) > 255:
            message = message[:255]
        if message[:-1] != "\x00":
            message = "".join([message, "\x00"])
        self.print_message_loop(line, message)

    def print_message_loop(self, line, message):
        if message == "":
            return
        self.lock.acquire()
        self.s.write_i2c_block_data(signAddress, line, [ord(x) for x in message[0:payLoadLen]])
        self.lock.release()
        self.print_message_loop(line, message[payLoadLen:])

    def get_status(self):
        self.lock.acquire()
        labStatus = self.s.read_byte(signAddress)
        self.lock.release()
        return labStatus
Exemplo n.º 4
0
class PiGlow:
	i2c_addr = 0x54 # fixed i2c address of SN3218 ic
	bus = None

	def __init__(self, i2c_bus=1):
		self.bus = SMBus(i2c_bus)

        # first we tell the SN3218 to enable output (turn on)
		self.write_i2c(CMD_ENABLE_OUTPUT, 0x01)

        # then we ask it to enable each bank of LEDs (0-5, 6-11, and 12-17)
		self.write_i2c(CMD_ENABLE_LEDS, [0xFF, 0xFF, 0xFF])

	def update_leds(self, values):
		#print "update pwm"
		self.write_i2c(CMD_SET_PWM_VALUES, values)
		self.write_i2c(CMD_UPDATE, 0xFF)

	# a helper that writes the given value or list of values to the SN3218 IC
	# over the i2c protocol
	def write_i2c(self, reg_addr, value):
        # if a single value is provided then wrap it in a list so we can treat
        # all writes in teh same way
		if not isinstance(value, list):
			value = [value];

        # write the data to the SN3218
		self.bus.write_i2c_block_data(self.i2c_addr, reg_addr, value)
Exemplo n.º 5
0
class mcp(object):
  """Driver for mcp4725 DAC."""

  _ADDRESS = 0x61
  _WRITEDAC = 0x40        #Write data directly to DAC.
  _WRITEDACEEPROM = 0x60  #Write data to DAC and to EEPROM for persistent value accross resets.

  def __init__( self ):
    super(mcp, self).__init__()
    self._i2c = SMBus(1)
    self._buffer = [0, 0]
    self.seteprom(0)

  def set( self, aValue ):
    ''' Set the DAC to the given value which is only 12 bits in size (0xFFF). '''

    self._buffer[0] = aValue >> 4
    self._buffer[1] = (aValue & 0xF) << 4
    self._i2c.write_i2c_block_data(mcp._ADDRESS, mcp._WRITEDAC, self._buffer)

  def seteprom( self, aValue ):
    ''' Set the DAC to the given value which is only 12 bits in size (0xFFF). '''

    self._buffer[0] = aValue >> 4
    self._buffer[1] = (aValue & 0xF) << 4
    self._i2c.write_i2c_block_data(mcp._ADDRESS, mcp._WRITEDACEEPROM, self._buffer)
class motorControlBoard:
    """Class to allow communication with the motor
       control board built by me using I2C."""
    __board_I2C_address = 0

    def __init__(self, board_address):
        if isinstance(board_address, int):
            if board_address > 0 and board_address < 0x78:
                self.__board_I2C_address = board_address
            else:
                raise Exception("Board address must be an integer between 0 and 0b1111000 (=120) exclusive.")
        else:
                raise Exception("Board address must be an integer.")
        self.__bus = SMBus(1)   # FIXME = have an option to make this zero for the old Raspberry Pis

    def set_speeds(self, left_speed, right_speed):
        # Enforce limits due to 8-bit resolution
        if(left_speed < -0xff):		left_speed = -0xff
        if(left_speed > +0xff):		left_speed = +0xff
        # Enforce limits due to 8-bit resolution
        if(right_speed < -0xff):	right_speed = -0xff
        if(right_speed > +0xff):	right_speed = +0xff

        direction = 0x00;
        if(left_speed < 0):     direction |= MOTOR_CONTROL_LEFT_BACK
        elif(left_speed > 0):   direction |= MOTOR_CONTROL_LEFT_FORE
        if(right_speed < 0):    direction |= MOTOR_CONTROL_RIGHT_BACK
        elif(right_speed > 0):  direction |= MOTOR_CONTROL_RIGHT_FORE

        self.__bus.write_i2c_block_data(self.__board_I2C_address, MOTOR_CONTROL_SET_DIR_SPEED_CMD, [direction, abs(left_speed), abs(right_speed)])
Exemplo n.º 7
0
class LEDSign:
    def __init__(self):
        self.s = SMBus(0)
        self.lock = Lock()

    def print_message(self, line, message):
        if len(message) > 255:
            message = message[:255]
        if message[:-1] != "\x00":
            message = ''.join([message, "\x00"])
        self.print_message_loop(line, message)

    def print_message_loop(self, line, message):
        if message == "":
            return
        self.lock.acquire()
        self.s.write_i2c_block_data(signAddress, line,
                                    [ord(x) for x in message[0:payLoadLen]])
        self.lock.release()
        self.print_message_loop(line, message[payLoadLen:])

    def get_status(self):
        self.lock.acquire()
        labStatus = self.s.read_byte(signAddress)
        self.lock.release()
        return labStatus
Exemplo n.º 8
0
class AM2320(object):
    """
    AM2320 temperature and humidity sensor class.

    :param interface:  I2C interface id.
    :type interface: :int
    :param sensor_address: AM2320 sensor I2C address. Optional, default 0x5C (92).
    :type sensor_address: int
    """

    def __init__(self, interface, sensor_address=0x5c):
        self.interface = interface
        self.address = sensor_address
        self.temperature = -1000.0
        self.humidity = -1
        self.bus = SMBus(interface)

    def _read_raw(self, command, regaddr, regcount):
        try:
            self.bus.write_i2c_block_data(self.address, 0x00, [])
            self.bus.write_i2c_block_data(self.address, command, [regaddr, regcount])

            sleep(0.002)

            buf = self.bus.read_i2c_block_data(self.address, 0, 8)
        except IOError, exc:
            raise CommunicationError(str(exc))

        buf_str = "".join(chr(x) for x in buf)

        crc = unpack('<H', buf_str[-2:])[0]
        if crc != self._am_crc16(buf[:-2]):
            raise CommunicationError("AM2320 CRC error.")
        return buf_str[2:-2]
Exemplo n.º 9
0
    def set_comp(self, t, h):

        # don't know if a value of 0.0% RH is allowed
        # so make minimun RH 0.01%
        if h < 0.1:
            h = 0.01

        if t < -25.0:
            t = -25.0

        rh = h * 2.0
        rh_i = int(rh // 1)
        rh_i &= 0xff
        #rh_d = int( (rh % 1) * 256 )
        # per CC-803-AN rev 6, AMS writes zero to fractional byte
        rh_d = 0x00

        # per datasheet 25 degree offset
        th = (t + 25) * 2.0
        th_i = int(th // 1)
        th_i &= 0xff
        #th_d = int( (th % 1) * 256 )
        # per CC-803-AN tev 6, AMS writes zero to fractional byte
        th_d = 0x00

        msg = [rh_i, rh_d, th_i, th_d]

        print "ccs811.set_comp() set T: %.1f RH: %.1f" % (t, h)
        print "ccs811.set_comp() regs. 0x%02x 0x%02x 0x%02x 0x%02x" % (
            th_i, th_d, rh_i, rh_d)

        bus = SMBus(I2CBUS)
        bus.write_i2c_block_data(self.I2Caddr, CCS811_REG_ENV_DATA, msg)
        bus.close()
        return
Exemplo n.º 10
0
class PiGlowService(rpyc.Service):

	def on_connect(self):
		pass

	def on_disconnect(self):
		pass

	def exposed_init(self):
		self.bus = SMBus(1)
		self.bus.write_byte_data(0x54, 0x00, 0x01)
		self.bus.write_byte_data(0x54, 0x13, 0xFF)
		self.bus.write_byte_data(0x54, 0x14, 0xFF)
		self.bus.write_byte_data(0x54, 0x15, 0xFF)

	def exposed_colours(self, red, orange, yellow, green, blue, white):
		try:
			self.bus.write_i2c_block_data(0x54, 0x01, [red, orange, yellow, green, blue, green, red, orange, yellow, white, white, blue, white, green, blue, yellow, orange, red])
			self.bus.write_byte_data(0x54, 0x16, 0xFF)
		except IOError:
			pass

	def exposed_all_off(self):
		try:
			self.bus.write_i2c_block_data(0x54, 0x01, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
			self.bus.write_byte_data(0x54, 0x16, 0xFF)
		except IOError:
			pass
Exemplo n.º 11
0
    def _set_regs(self, register, value):

        bus = SMBus(I2CBUS)
        if isinstance(value, int):
            bus.write_byte_data(self.i2c_addr, register, value)
        else:
            bus.write_i2c_block_data(self.i2c_addr, register, value)
        bus.close()
Exemplo n.º 12
0
class Bus_Hepler_i2c():
	def __init__(self, bus_location=1):
		self.bus = SMBus(bus_location)
		
	def write_byte(self, address, register, byte):
		self.bus.write_i2c_block_data(address, register, [byte])
		
	def read_block_data(self, address, cmd): 
		return self.bus.read_i2c_block_data(address, cmd)
Exemplo n.º 13
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)
Exemplo n.º 14
0
class rigmi2c(object):
    def __init__(self):
        self.bus = SMBus(1)
        self.addr = 42

    def readall(self):
        try:
            data = self.bus.read_i2c_block_data(self.addr, 1, 32)
            rd = []
            for i in range(8):
                rd.append(data[4 * i] | (data[1 + 4 * i] << 8)
                          | (data[2 + 4 * i] << 16) | (data[3 + 4 * i] << 24))
            return rd
        except Exception as e:
            print(e)
            try:
                self.__init__()
            except Exception as f:
                pass
            return None

    def _writeReg(self, cmd, addr, val):
        try:
            addr &= 0xf
            cmd &= 0xf
            c = (cmd << 4) | addr
            d3 = (val >> 24) & 0xff
            d2 = (val >> 16) & 0xff
            d1 = (val >> 8) & 0xff
            d0 = val & 0xff
            self.bus.write_i2c_block_data(self.addr, c, [d3, d2, d1, d0])
            time.sleep(0.30)  # necessary to avoid some kind of i2c error
            return True
        except Exception as e:
            print('- Error writing to i2c device.')
            print(e)
            try:
                print('- attempting to restart i2c')
                self.__init__()
                print(self.readall())
            except Exception as f:
                pass
        return False

    def setWord(self, addr, bits):
        return self._writeReg(0, addr, bits)

    def setBits(self, addr, bits):
        return self._writeReg(1, addr, bits)

    def clrBits(self, addr, bits):
        return self._writeReg(2, addr, bits)

    def tglBits(self, addr, bits):
        return self._writeReg(3, addr, bits)
Exemplo n.º 15
0
class rigmi2c(object):
    def __init__(self):
        self.bus = SMBus(1)
        self.addr = 42

    def readall(self):
        try:
            data = self.bus.read_i2c_block_data(self.addr, 1, 32)
            time.sleep(0.050)  # necessary to avoid some kind of i2c error
            rd = []
            for i in range(16):
                rd.append(data[2 * i] | (data[1 + 2 * i] << 8))
            return rd
        except Exception as e:
            print("Exception while reading.")
            print(e)
            self.reset_Ard()
            return None

    def _writeReg(self, cmd, addr, val):
        addr &= 0xf
        cmd &= 0xf
        c = (cmd << 4) | addr
        d1 = (val >> 8) & 0xff
        d0 = val & 0xff
        try:
            self.bus.write_i2c_block_data(self.addr, c, [d1, d0])
        except Exception as e:
            self.reset_Ard()

        time.sleep(0.050)  # necessary to avoid some kind of i2c error

    def reset_Ard(self):
        print('Resetting Atmega')
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(7, GPIO.OUT)
        GPIO.output(7, GPIO.LOW)
        GPIO.output(7, GPIO.HIGH)
        time.sleep(0.020)
        GPIO.output(7, GPIO.LOW)
        GPIO.setup(7, GPIO.IN)

    def setWord(self, addr, bits):
        self._writeReg(0, addr, bits)

    def setBits(self, addr, bits):
        self._writeReg(1, addr, bits)

    def clrBits(self, addr, bits):
        self._writeReg(2, addr, bits)

    def tglBits(self, addr, bits):
        self._writeReg(3, addr, bits)
Exemplo n.º 16
0
def StartBootloaderI2C(addr):
    print("Starting bootloader \n")
    try:
        bus = SMBus(1)
        #startCmd = [0xFE, 0x01, 0xFE]
        bus.write_i2c_block_data(addr, 0xFE, [0x01, 0xFE])
        time.sleep(0.01)  #usleep(10000)
        print("Starting bootloader old firmware\n")
        bus.write_i2c_block_data(addr, 0xFE, [0x01])
        time.sleep(0.01)
    except:
        return
Exemplo n.º 17
0
def get_status(command, value):
  status = ""
  bus = SMBus(i2cBusAddr)
  BytesToSend = convert_string_to_bytes(value)
  bus.write_i2c_block_data(arduinoSlaveAddress, ord(command), BytesToSend)
  time.sleep(0.001)
  for i in range (0, 11):
    statusChr = chr(bus.read_byte(arduinoSlaveAddress))
    if statusChr != ";":
      status += statusChr
    else:
      break
  bus.close()
  return status
Exemplo n.º 18
0
    def set_baseline(self, hi, lo):
        msg = [hi, lo]

        bus = SMBus(I2CBUS)
        resp = bus.write_i2c_block_data(self.I2Caddr, CCS8_REG_BASELINE, msg)
        bus.close()
        return
Exemplo n.º 19
0
class I2C:

    mutex = Lock()

    @classmethod
    def start(self):
        try:
            self.bus = SMBus(1)
            sleep(0.5)
        except Exception as e:
            Logger.warn("Could not found i2c bus : " + str(e))

    @classmethod
    def write_reg(self, ip, register, data):
        self.mutex.acquire()
        try:
            self.bus.write_byte_data(ip, register, data)
        except Exception as e:
            Logger.error("I2C write reg error : " + str(e))
        sleep(0.01)  # to make sure all the infos are sent
        self.mutex.release()

    @classmethod
    def write_data(self, ip, data):
        self.mutex.acquire()
        try:
            self.bus.write_i2c_block_data(ip, 0, data)
        except Exception as e:
            Logger.error("I2C write data error : " + str(e))
            self.mutex.release()
            return 1
        sleep(0.01)
        self.mutex.release()
        return 0

    @classmethod
    def read_reg(self, ip, register):
        self.mutex.acquire()
        try:
            data = self.bus.read_byte_data(ip, register)
        except Exception as e:
            Logger.error("I2C read reg error : " + str(e))
            self.mutex.release()
            return None
        sleep(0.01)
        self.mutex.release()
        return data
Exemplo n.º 20
0
class I2CBacklight:
    """Dimming by I2C / SMBUS."""

    def __init__(self, bus: int, address: int, offset: int,
                 values: PercentageMap):
        """Sets the respective I2C configuration."""
        try:
            self.smbus = SMBus(bus)
        except FileNotFoundError:
            raise DoesNotExist() from None

        self.address = address
        self.offset = offset
        self.values = values

    @property
    def max(self):
        """Returns the maximum raw value."""
        return max(self.values)

    @property
    def raw(self):
        """Returns the raw set value."""
        return self._read(self.offset)

    @raw.setter
    def raw(self, value):
        """Sets the raw value."""
        if value in self.values:
            return self._write(self.offset, value)

        raise ValueError(value)

    @property
    def percent(self):
        """Returns the current brightness in percent."""
        range_ = self.values[self.raw]
        return sum(range_) / len(range_)

    @percent.setter
    def percent(self, percent):
        """Returns the current brightness in percent."""
        if 0 <= percent <= 100:
            self.raw = self.values.from_percent(percent)
        else:
            raise ValueError(f'Invalid percentage: {percent}.')

    def _read(self, address: int) -> int:
        """Reads the respective address."""
        return self.smbus.read_i2c_block_data(
            self.address, address, 1)[0]

    def _write(self, address: int, value: int):
        """Reads the respective address."""
        return self.smbus.write_i2c_block_data(
            self.address, address, [value])
Exemplo n.º 21
0
class I2CBus:
    def __init__(self, bus_number=1):
        self.bus = SMBus(bus_number)
        self.lock = threading.Lock()

    def write_data(self, address, cmd, data_list):
        with self.lock:
            try:
                self.bus.write_i2c_block_data(address, cmd, data_list)
                return 1
            except OSError as my_error:
                print("CAN`T WRITE DATA. ERROR: ", my_error)
                return 0

    def read_data(self, address, register, number_of_bytes):
        with self.lock:
            try:
                recieved_data = self.bus.read_i2c_block_data(address, register, number_of_bytes)
                return recieved_data
            except OSError as my_error:
                print("CAN`T READ DATA. ERROR: ", my_error)
                return 0
Exemplo n.º 22
0
class ArduinoCommunicator:
    def __init__(self, arduino_address):
        self.address = arduino_address
        self.bus = SMBus(1)
        self.write_attempt = 0
        self.data_from_arduino = dict.fromkeys(["IMU data"])
        self.UPDATE_SEND_REGISTER = 11

        self.data_to_arduino_register = {
            "cone_x": 1,
            "cone_y": 2
        }

        self.SIZE_OF_ARDUINO_SEND_REGISTERS = 8

    def write_float_to_register(self, num, register):
        """
        Writes a float into the Arduino's receive register
        """

        if register < 0 or register > 7:
            raise Exception("Error in write float: register must be in [0,7]")
        data = list(bytearray(str(num), 'utf8'))
        self._write(register, data)

    def _write(self, register, data):
        timeout = 10
        try:
            self.bus.write_i2c_block_data(self.address, register, data)
            self.write_attempt = 0
        except Exception as e:
            self.write_attempt += 1
            if self.write_attempt < timeout:
                print("Failed to write due to Exception " + str(e) + ". Trying again")
                self._write(register, data)
            else:
                print("Timed out writing")
                traceback.print_exc()
Exemplo n.º 23
0
class i2c_interface:
    def __init__(self, address=0x3c):
        """
        :param address: i2c address of ssd1306
        """
        self.bus = SMBus(self.bus_id())
        self.address = address

    def __del__(self):
        self.close_i2c()

    def close_i2c(self):
        self.bus.close()

    def bus_id(self):
        """
        :return: Returns SMBUS id of Raspberry Pi
        """
        revision = [
            lines[12:-1] for lines in open('/proc/cpuinfo', 'r').readlines()
            if "Revision" in lines[:8]
        ]
        revision = (revision + ['0000'])[0]
        return 1 if int(revision, 16) >= 4 else 0

    def i2c_read(self, register=0):
        data = self.bus.read_byte_data(self.address, register)
        return data

    def i2c_write(self, register=DISPLAY_START_LINE, data=0):
        # Write a byte to address, register
        self.bus.write_byte_data(self.address, register, data)

    def i2c_write_block(self, register=DISPLAY_START_LINE, data=None):
        if data is None:
            data = [40]
        self.bus.write_i2c_block_data(self.address, register, data)
Exemplo n.º 24
0
class MB85RC04:
	def __init__(self, I2C_bus_number = 1,  address = 0x50):
		self.bus = SMBus(I2C_bus_number)
		self.address = address


	def readByte(self, registerAddress):
		if(registerAddress > 255):
			self.address = self.address | 1
			registerAddress = registerAddress - 256
		else:
			self.address = self.address & 0xFE	
		return self.bus.read_byte_data(self.address, registerAddress)
	
	def writeByte(self, registerAddress, data):
		if(registerAddress > 255):
                        self.address = self.address | 1
                        registerAddress = registerAddress - 256
                else:
                        self.address = self.address & 0xFE
                self.bus.write_byte_data(self.address, registerAddress, data)

	def readBytes(self, registerAddress):
                if(registerAddress > 255):
                        self.address = self.address | 1
                        registerAddress = registerAddress - 256
                else:
                        self.address = self.address & 0xFE
                return self.bus.read_i2c_block_data(self.address, registerAddress)
	
	def writeBytes(self, registerAddress, data):
                if(registerAddress > 255):
                        self.address = self.address | 1
                        registerAddress = registerAddress - 256
                else:
                        self.address = self.address & 0xFE
                self.bus.write_i2c_block_data(self.address, registerAddress, data)
Exemplo n.º 25
0
class MB85RC04:
    def __init__(self, I2C_bus_number=1, address=0x50):
        self.bus = SMBus(I2C_bus_number)
        self.address = address

    def readByte(self, registerAddress):
        if (registerAddress > 255):
            self.address = self.address | 1
            registerAddress = registerAddress - 256
        else:
            self.address = self.address & 0xFE
        return self.bus.read_byte_data(self.address, registerAddress)

    def writeByte(self, registerAddress, data):
        if (registerAddress > 255):
            self.address = self.address | 1
            registerAddress = registerAddress - 256
        else:
            self.address = self.address & 0xFE
        self.bus.write_byte_data(self.address, registerAddress, data)

    def readBytes(self, registerAddress):
        if (registerAddress > 255):
            self.address = self.address | 1
            registerAddress = registerAddress - 256
        else:
            self.address = self.address & 0xFE
        return self.bus.read_i2c_block_data(self.address, registerAddress)

    def writeBytes(self, registerAddress, data):
        if (registerAddress > 255):
            self.address = self.address | 1
            registerAddress = registerAddress - 256
        else:
            self.address = self.address & 0xFE
        self.bus.write_i2c_block_data(self.address, registerAddress, data)
Exemplo n.º 26
0
class sn3218:
	i2c_addr = 0x54
	bus = None
	values = [0x00] * 18
	
	def __init__(self, i2c_bus=1):
		self.bus = SMBus(i2c_bus)

		# Enable output
		self.write(CMD_ENABLE_OUTPUT, 0x01)
		# Enable LEDs ( 0-5, 6-11, 12-17 )
		self.write(CMD_ENABLE_LEDS, [0xFF, 0xFF, 0XFF])

	def setList(self, pins, values):
		if not isinstance(pins, list) and isinstance(values, list):
			for i, v in enumerate(values):
				self.set( (i+pins) % 18, v )
		elif isinstance(pins, list) and isinstance(values, list):
			if len(pins) == len(values):
				for i, v in enumerate(values):
					self.set( pins[i], v)
			else:
				raise ValueError(TXT_LIST_LEN_MISMATCH)
				return False
		elif isinstance(pins, list) and not isinstance(values, list):
			for i, p in enumerate(pins):
				self.set( p, values );
		return True

	def set(self, pin, value):
		if isinstance(value, list) or isinstance(pin, list):
			return self.setList( pin, value )

		if pin > 17 or pin < 0:
			raise ValueError(TXT_OUT_OF_RANGE)
			return False
		if value > 255 or value < 0:
			raise ValueError(TXT_PWM_INVALID)
			return False
		self.values[pin] = value
		return True

	def get(self, pin, value):
		if pin > 17 or pin < 0:
			raise ValueError(TXT_OUT_OF_RANGE)
			return False
		if value > 255 or value < 0:
			raise ValueError(TXT_PWM_INVALID)
			return False
		return self.values[pin]

	def update(self):
		self.write(CMD_SET_PWM_VALUES, self.values)
		self.write(CMD_UPDATE, 0xFF)

	def write(self, reg_addr, value):
		# Treat all writes as block writes
		if not isinstance(value, list):
			value = [value]

		self.bus.write_i2c_block_data(self.i2c_addr, reg_addr, value)
Exemplo n.º 27
0
from smbus import SMBus
import time
import datetime
import calendar
import sys, getopt

i2cbus=SMBus(1)

def _GetChecksum(data):
	fcs=0xFF
	for x in data[:]:
		fcs=fcs^x
	return fcs

data = [0x55, 0x26, 0xa0, 0x2b]
fcs = _GetChecksum(data)
d = data[:]
d.append(fcs)

i2cbus.write_i2c_block_data(0x14, 248, d) 
Exemplo n.º 28
0
class ADS1015:
    """ Class ro read analog values"""
    #control constants
    _SLAVE_ADDR = 0x48
    # pointer register
    _POINTER_REG_CONVERSION = 0x00
    _POINTER_REG_CONFIG     = 0x01

    # configuration register
    _CONFIG_REG_MUX_CH0 = 0x04
    _CONFIG_REG_MUX_CH1 = 0x05
    _CONFIG_REG_MUX_CH2 = 0x06
    _CONFIG_REG_MUX_CH3 = 0x07
    _CONFIG_REG_PGA_6144 = 0x00
    _CONFIG_REG_PGA_4096 = 0x01
    _CONFIG_REG_MODE_CONT = 0x00
    _CONFIG_REG_MODE_SING = 0x01
    _CONFIG_REG_DR_250SPS = 0x01
    _CONFIG_REG_COMP_OFF = 0x3

    def __init__(self,device_number,channel):
        """ """
        try:
            self.bus = SMBus(device_number)
        except Exception:
            raise i2cError()

        try:
            if channel ==3:
                self.CH = self._CONFIG_REG_MUX_CH3
            elif channel == 2:
                self.CH = self._CONFIG_REG_MUX_CH2
            elif channel == 1:
                self.CH = self._CONFIG_REG_MUX_CH1
            else:
                self.CH = self._CONFIG_REG_MUX_CH0

            # MUX PGA MODE DR COMP_QUE
            confList =  [ self.CH,      \
                          self._CONFIG_REG_PGA_4096,     \
                          self._CONFIG_REG_MODE_CONT,    \
                          self._CONFIG_REG_DR_250SPS,    \
                          self._CONFIG_REG_COMP_OFF ]
            self.configADS1015(confList)
            # set conversion factor
            if confList[1] == self._CONFIG_REG_PGA_6144:
                self.convFactor = 6.144*2.0/4096
            elif confList[1] == self._CONFIG_REG_PGA_4096:
                self.convFactor = 4.096*2.0/4096



        except Exception as e:
            print(e)
            raise ConfigError()

    def configADS1015(self, list):
        """ configure the chip according to list"""
        MSB = (list[0]<<4)+ (list[1]<<1) + list[2]
        LSB = (list[3]<<5) + list[4]

        # write list to config register
        self.bus.write_i2c_block_data(self._SLAVE_ADDR,self._POINTER_REG_CONFIG,[MSB, LSB])
        if DEBUG:
            print("configList:", list)
            print("MSB: ", MSB, "LSB: ", LSB)
            #read register back
            Data = self.bus.read_i2c_block_data(self._SLAVE_ADDR,self._POINTER_REG_CONFIG)[:2]
            #print ( "To be written: ",MSB, LSB)
            print (" Read back :  ",Data[0], Data[1])


    def readAnalogChannel(self):
        """ reads single ended analog channel"""
        #read config register and overwrite MUX
        configTmp = self.bus.read_i2c_block_data(self._SLAVE_ADDR,self._POINTER_REG_CONFIG)[:2]
        bitmask  = 0x8F
        tmp = (configTmp[0] & bitmask)|(self.CH << 4)
        self.bus.write_i2c_block_data(self._SLAVE_ADDR,self._POINTER_REG_CONFIG,[tmp,configTmp[1]])
        # get conversion value
        tmp = self.bus.read_i2c_block_data(self._SLAVE_ADDR,self._POINTER_REG_CONVERSION)[:2]
        val = ((tmp[0] << 8) + tmp[1]) >> 4

        return val * self.convFactor
class Board:
	# Methods list
	# * __init__(gpio_en, gpio_stby, i2cbus = None, gpio_mode_bcm = False)
	# * power(on = None)
	# * reset()
	# * mute(on = None)
	
	# Constants list
	# * DSP - holding instance of DSP control class
	# * TUNER - holding instance of TUNER control class
	
	# Internal variables list
	# * _gpio_en - GPIO pin connected to the EN pin of the board
	# * _gpio_stby - GPIO pin connected to the ST-BY pin of the board
	# * _bus - holding instance of SMBus providing I2C bus for communication with chips on the board
	# * _state - dictionary holding current setup of the board
	
	
	#*
	#* Inits class
	#* @param int gpio_en - GPIO pin connected to the EN pin of board
	#* @param int gpio_stby - GPIO pin connected to the ST-BY pin of board
	#* @param int i2cbus - number of i2c bus the board is connected to
	#* @param bool gpio_mode_bcm - if the mode of GPIO module used for specifying GPIO pins is BCM (True) or BOARD (False)
	#*
	def __init__(self, gpio_en, gpio_stby, i2cbus = None, gpio_mode_bcm = False):
		if i2cbus == None:
			raise Exception()#TODO auto selection based on RPI board revision
		
		self._gpio_en = gpio_en
		self._gpio_stby = gpio_stby
		
		self._bus = SMBus(i2cbus)
		sleep(0.5)
		
		GPIO.setmode(GPIO.BCM if gpio_mode_bcm else GPIO.BOARD)
		GPIO.setup(self._gpio_en, GPIO.OUT, GPIO.LOW)
		GPIO.setup(self._gpio_stby, GPIO.OUT, GPIO.LOW)
		
		self._state = {
			"power": False,
			"mute": True
		}
		
		self.DSP = DSP(self)
		self.TUNER = TUNER(self)
		
		# init GPIOs
		self.power(False)
		self.mute(True)
	# end of method __init__
	
	#*
	#* Destructor
	#*
	def __del__(self):
		self.power(False)
		GPIO.cleanup()
	# end of method __del__
	
	
	#*
	#* Turns on-board voltage regulators on or off
	#* @param bool on - True/False for setting the power state, None to return current state only
	#* @return bool - if the voltage regulators are on or off (software only)
	#*
	def power(self, on = None):
		if on != None:
			old_state = self._state["power"]
			
			self._state["power"] = bool(on)
			
			if not self._state["power"]:
				self.mute(True)
				self.DSP.beforePowerOff()
				self.TUNER.beforePowerOff()
				sleep(0.2)
			
			GPIO.output(self._gpio_en, self._state["power"])
			
			if not old_state and self._state["power"]:
				sleep(0.5)
				self.DSP.afterPowerOn()
				self.TUNER.afterPowerOn()
		
		return self._state["power"]
	# end of method power
	
	#*
	#* Resets board by turning it off and then on after 2 seconds
	#*
	def reset(self):
		self.power(False)
		sleep(2)
		self.power(True)
	# end of method reset
	
	#*
	#* Enables or disables amplifier stand-by mode
	#* @param bool on - True/False for setting the mute, None to return current state only
	#* @return bool - if the amplifier is muted or not (software only)
	#*
	def mute(self, on = None):
		if on != None:
			on = bool(on)
			
			if self._state["power"] or on:
				self._state["mute"] = on
				GPIO.output(self._gpio_stby, not self._state["mute"])
		
		return self._state["mute"]
	# end of method mute
	
	
	#*
	#* Send data over I2C if the Board is powered on
	#* @param int address - address byte
	#* @param tuple/list data - data bytes to be sent
	#*
	def _i2c_write(self, address, data):
		if address < 0 or len(data) < 1:
			return
		
		if not self._state["power"]:# send data to board but only if it is powered
			return
		
		if len(data) > 1:
			self._bus.write_i2c_block_data(address, data[0], data[1:])
		else:
			self._bus.write_byte(address, data[0])
Exemplo n.º 30
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))))
Exemplo n.º 31
0
class MPL115A2:

    # select the SMBus channel (depends on RaspberryPI model)
    bus = SMBus(0)

    # the I2C address of the MPL115A2 sensor
    # default is 0x60
    MPL115A2_ADDRESS = (0x60)

    # the register addresses of the MPL115A2 sensor
    MPL115A2_REGISTER_PRESSURE_MSB = (0x00)
    MPL115A2_REGISTER_PRESSURE_LSB = (0x01)
    MPL115A2_REGISTER_TEMP_MSB = (0x02)
    MPL115A2_REGISTER_TEMP_LSB = (0x03)
    MPL115A2_REGISTER_A0_COEFF_MSB = (0x04)
    MPL115A2_REGISTER_A0_COEFF_LSB = (0x05)
    MPL115A2_REGISTER_B1_COEFF_MSB = (0x06)
    MPL115A2_REGISTER_B1_COEFF_LSB = (0x07)
    MPL115A2_REGISTER_B2_COEFF_MSB = (0x08)
    MPL115A2_REGISTER_B2_COEFF_LSB = (0x09)
    MPL115A2_REGISTER_C12_COEFF_MSB = (0x0A)
    MPL115A2_REGISTER_C12_COEFF_LSB = (0x0B)
    MPL115A2_REGISTER_STARTCONVERSION = (0x12)

# some private variables
    a0_MSB = -1
    a0_LSB = -1
    b1_MSB = -1
    b1_LSB = -1
    b2_MSB = -1
    b2_LSB = -1
    c12_MSB = -1
    c12_LSB = -1

    _mpl115a2_a0 = -1
    _mpl115a2_b1 = -1
    _mpl115a2_b2 = -1
    _mpl115a2_c12 = -1

    pressure_MSB = -1
    pressure_LSB = -1

    temp_MSB = -1
    temp_LSB = -1

    temperature = -1
    pressure = -1

    def __init__(self, address=0x60, smbus=0, debug=True):
        self.bus = SMBus(smbus)
        self.MPL115A2_ADDRESS = address
        self.debug = debug

        # one time read factory calibrated coefficients from sensor
        # Read the calibration data
        self.read_coefficients()
        # pass

    # initiate conversion inside the sensor before metrics reading
    def start_convert(self):
        # send conversion command needed for pressure reading
        self.bus.write_i2c_block_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_STARTCONVERSION,
            [0x12])
        #
        # sleep until the conversion is certainly completed
        time.sleep(0.3)

    def read_raw_data(self):
        # prepare sensor for reading
        self.start_convert()
        # read pressure AGC units
        self.pressure_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_PRESSURE_MSB)
        self.pressure_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_PRESSURE_LSB)

        # read raw temperature AGC units
        self.temp_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_TEMP_MSB + 0)
        self.temp_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_TEMP_LSB + 0)

        # build
        self.temperature = (self.temp_MSB << 8 | self.temp_LSB) >> 6
        self.pressure = (self.pressure_MSB << 8 | self.pressure_LSB) >> 6
        
        self.debug_output(" Raw temperature: " + str(self.temperature))
        self.debug_output(" Raw pressure: " + str(self.pressure))
        

    def read_raw_temperature(self):
        # read raw temperature AGC units
        self.temp_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_TEMP_MSB + 0)
        self.temp_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_TEMP_LSB + 0)

        # build
        self.temperature = (self.temp_MSB << 8 | self.temp_LSB) >> 6

    # returns Temperature in Celsius Float
    def read_temperature(self):
        self.read_raw_temperature()
        return (self.temperature - 498.0) / -5.35 + 25.0

    # returns Pressure reading in Pa Float
    def read_pressure(self):
        self.read_raw_data()
        pressureComp = self._mpl115a2_a0 + \
            (self._mpl115a2_b1 + self._mpl115a2_c12 * self.temperature) * \
            self.pressure + self._mpl115a2_b2 * self.temperature
        press =  ((65.0 / 1023.0) * pressureComp) + 50.0
        return press


    def read_both(self):
        self.read_raw_data()
        pressureComp = self._mpl115a2_a0 + \
            (self._mpl115a2_b1 + self._mpl115a2_c12 * self.temperature) * \
            self.pressure + self._mpl115a2_b2 * self.temperature
        temp = (self.temperature - 498.0) / -5.35 + 25.0
        press = ((65.0 / 1023.0) * pressureComp) + 50.0
        return {'temperature': temp, 'pressure': press}

    # read the factory coefficients from the sensor
    def read_coefficients(self):

        self.a0_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_A0_COEFF_MSB +
            0)
        self.a0_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_A0_COEFF_LSB +
            0)

        self.b1_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_B1_COEFF_MSB +
            0)
        self.b1_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_B1_COEFF_LSB +
            0)

        self.b2_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_B2_COEFF_MSB +
            0)
        self.b2_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_B2_COEFF_LSB +
            0)

        self.c12_MSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_C12_COEFF_MSB +
            0)
        self.c12_LSB = self.bus.read_byte_data(
            self.MPL115A2_ADDRESS,
            self.MPL115A2_REGISTER_C12_COEFF_LSB +
            0)
        # unpack to 10bits full scale
        self._mpl115a2_a0 = (float)(
            (self.a0_MSB << 8) | self.a0_LSB) / (2 << 3)
        self._mpl115a2_b1 = (float)(
            (self.b1_MSB << 8) | self.b1_LSB) / (2 << 13)
        self._mpl115a2_b2 = (float)(
            (self.b2_MSB << 8) | self.b2_LSB) / (2 << 14)
        self._mpl115a2_c12 = (float)(
            (self.c12_MSB << 8) | (self.c12_LSB >> 2)) / (2 << 13)

    def debug_output(self, message):
        if (self.debug):
            print "DEBUG: (" + inspect.stack()[1][3] +")" + str(message)
Exemplo n.º 32
0
# Initial MCP23017 config:
bus.write_byte_data(addr, 0x05  , 0x00) # If bank 1, switch to 0
bus.write_byte_data(addr, IOCONA, 0x44) # Bank 0, INTB=A, seq, OD IRQ

# Read/modify/write remaining MCP23017 config:
cfg = bus.read_i2c_block_data(addr, IODIRA, 14)
cfg[ 0] = 0xFF # Input bits
cfg[ 1] = 0xFF
cfg[ 2] = 0x00 # Polarity
cfg[ 3] = 0x00
cfg[ 4] = 0xFF # Interrupt pins
cfg[ 5] = 0xFF
cfg[12] = 0xFF # Pull-ups
cfg[13] = 0xFF
bus.write_i2c_block_data(addr, IODIRA, cfg)

# Clear interrupt by reading INTCAP and GPIO registers
x        = bus.read_i2c_block_data(addr, INTCAPA, 4)
oldState = x[2] | (x[3] << 8)

# Callback for MCP23017 interrupt request
def mcp_irq(pin):
	global oldState
	x = bus.read_i2c_block_data(addr, INTCAPA, 4)
	newState = x[2] | (x[3] << 8)
	for i in range(16):
		bit = 1 << i
		lvl = newState & bit
		if lvl != (oldState & bit):
			ui.write(e.EV_KEY, key[i], 0 if lvl else 1)
Exemplo n.º 33
0
    global _on_move
    _on_move = handler
  return register


def airwheel():
  '''
  Bind an action to the "airhweel" gesture

  Point your finger at the Skywriter and spin it in a wheel
  The handler will receive a rotation delta in degrees
  '''
  def register(handler):
    global _on_airwheel
    _on_airwheel = handler
  return register


def _exit():
  stop_poll()
  if GPIO != None:
    GPIO.cleanup()


atexit.register(_exit)


reset()
i2c.write_i2c_block_data(SW_ADDR, 0xa1, [0b00000000, 0b00011111, 0b00000000, 0b00011111])
start_poll()
Exemplo n.º 34
0
class Mpl3115a2(object):
    _bus = None

    def __init__(self, i2c_bus=0):
        """
        :type i2c_bus: int specifying i2c bus number
        """
        self._bus = SMBus(i2c_bus)
        whoami = self._bus.read_byte_data(MPL3115A2_ADDRESS, MPL3115A2_WHOAMI)

        if whoami != 0xc4:
            print("MPL3115A2 not active.")
            exit(1)

        # Set MPL3115A2 oversampling to 128, put in Barometer mode, enabled standby on CTRL_REG1
        self._bus.write_byte_data(
            MPL3115A2_ADDRESS,
            MPL3115A2_CTRL_REG1,
            MPL3115A2_CTRL_REG1_SBYB |
            MPL3115A2_CTRL_REG1_OS128 |
            MPL3115A2_CTRL_REG1_BAR)

        # Configure MPL3115A2
        self._bus.write_byte_data(
            MPL3115A2_ADDRESS,
            MPL3115A2_PT_DATA_CFG,
            MPL3115A2_PT_DATA_CFG_TDEFE |
            MPL3115A2_PT_DATA_CFG_PDEFE |
            MPL3115A2_PT_DATA_CFG_DREM)

    def poll(self):
        sta = 0
        while not (sta & MPL3115A2_REGISTER_STATUS_PDR):
            sta = self._bus.read_byte_data(MPL3115A2_ADDRESS, MPL3115A2_REGISTER_STATUS)

    def get_altitude(self):
        # print "Reading Altitude Data..."
        self._bus.write_byte_data(
            MPL3115A2_ADDRESS,
            MPL3115A2_CTRL_REG1,
            MPL3115A2_CTRL_REG1_SBYB |
            MPL3115A2_CTRL_REG1_OS128 |
            MPL3115A2_CTRL_REG1_ALT)  # change to altimeter mode

        self.poll()

        msb, csb, lsb = self._bus.read_i2c_block_data(MPL3115A2_ADDRESS, MPL3115A2_REGISTER_PRESSURE_MSB, 3)
        # print msb, csb, lsb

        alt = float((((msb << 24) | (csb << 16) | lsb) * 10) / 65536)

        # correct sign
        if alt > (1 << 15):
            alt -= 1 << 16

        return alt

    def get_pressure(self):
        # print "Reading Pressure Data..."
        self._bus.write_byte_data(
            MPL3115A2_ADDRESS,
            MPL3115A2_CTRL_REG1,
            MPL3115A2_CTRL_REG1_SBYB |
            MPL3115A2_CTRL_REG1_OS128 |
            MPL3115A2_CTRL_REG1_BAR)  # change to barometer mode

        self.poll()

        msb, csb, lsb = self._bus.read_i2c_block_data(MPL3115A2_ADDRESS, MPL3115A2_REGISTER_PRESSURE_MSB, 3)
        # print msb, csb, lsb

        return ((msb << 16) | (csb << 8) | lsb) / 64.

    def calibrate(self):
        # print "Calibrating..."
        p = 0
        t = 0
        a = 0
        calibration_rounds = 5

        for _i in np.arange(0, calibration_rounds, 1):
            p += self.get_pressure()
            t += self.get_temperature()
            a += self.get_altitude()
            print("MPL3115A2 Calibration Round: {0} of {1}".format((_i+1), calibration_rounds))

        pa = int((p / 10) / 2)
        ta = (t / 10)
        aa = (a / 10)

        self._bus.write_i2c_block_data(MPL3115A2_ADDRESS, MPL3115A2_BAR_IN_MSB, [pa >> 8 & 0xff, pa & 0xff])

        return [pa, ta, aa]

    def get_temperature(self):
        # print "Reading Temperature Data..."

        self._bus.write_byte_data(
            MPL3115A2_ADDRESS,
            MPL3115A2_CTRL_REG1,
            MPL3115A2_CTRL_REG1_SBYB |
            MPL3115A2_CTRL_REG1_OS128 |
            MPL3115A2_CTRL_REG1_BAR)

        self.poll()

        t_data = self._bus.read_i2c_block_data(MPL3115A2_ADDRESS, MPL3115A2_REGISTER_STATUS_PDR, 2)
        # status = _bus.read_byte_data(MPL3115A2_ADDRESS, 0x00)

        # print t_data

        return t_data[0] + (t_data[1] >> 4) / 16.0
Exemplo n.º 35
0
#!/bin/env/python


# File: eeprom_setup.py
#
# Setup test data on the I2C EEPROM
#
# Date: 6/28/18
# Platform: Raspberry Pi 3 Model B
#
# Python Version: 2.7.9

from smbus import SMBus			# For I2C operations

vals = [0, 0, 5, 0, 1, 0, 245, 0, 2, 1, 245, 0, 3, 2, 244, 0, 4, 4, 244, 0, 5, 3, 243]

bus = SMBus(1)				# Declare "Bus" Object
bus.write_i2c_block_data(0x50, 0, vals)	# Write data to EEPROM
print "Finished"
Exemplo n.º 36
0
class PiGlow:

    def __init__(self):
        if rpi.RPI_REVISION == 1:
            i2c_bus = 0
        elif rpi.RPI_REVISION == 2:
            i2c_bus = 1
        elif rpi.RPI_REVISION == 3:
            i2c_bus = 1
        else:
            print "Unable to determine Raspberry Pi revision."
            exit

        self.bus = SMBus(i2c_bus)
        self.bus.write_i2c_block_data(0x54, 0x00, [0x01])
        self.bus.write_byte_data(0x54, 0x13, 0xFF)
        self.bus.write_byte_data(0x54, 0x14, 0xFF)
        self.bus.write_byte_data(0x54, 0x15, 0xFF)

    def white(self, value):
        self.bus.write_byte_data(0x54, 0x0A, value)
        self.bus.write_byte_data(0x54, 0x0B, value)
        self.bus.write_byte_data(0x54, 0x0D, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def blue(self, value):
        self.bus.write_byte_data(0x54, 0x05, value)
        self.bus.write_byte_data(0x54, 0x0C, value)
        self.bus.write_byte_data(0x54, 0x0F, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def green(self, value):
        self.bus.write_byte_data(0x54, 0x06, value)
        self.bus.write_byte_data(0x54, 0x04, value)
        self.bus.write_byte_data(0x54, 0x0E, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def yellow(self, value):
        self.bus.write_byte_data(0x54, 0x09, value)
        self.bus.write_byte_data(0x54, 0x03, value)
        self.bus.write_byte_data(0x54, 0x10, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def orange(self, value):
        self.bus.write_byte_data(0x54, 0x08, value)
        self.bus.write_byte_data(0x54, 0x02, value)
        self.bus.write_byte_data(0x54, 0x11, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def red(self, value):
        self.bus.write_byte_data(0x54, 0x07, value)
        self.bus.write_byte_data(0x54, 0x01, value)
        self.bus.write_byte_data(0x54, 0x12, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def all(self, value):
        v = value
        self.bus.write_i2c_block_data(
            0x54, 0x01, [v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v, v])
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def arm(self, arm, value):
        if arm == 1:
            self.bus.write_byte_data(0x54, 0x07, value)
            self.bus.write_byte_data(0x54, 0x08, value)
            self.bus.write_byte_data(0x54, 0x09, value)
            self.bus.write_byte_data(0x54, 0x06, value)
            self.bus.write_byte_data(0x54, 0x05, value)
            self.bus.write_byte_data(0x54, 0x0A, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)
        elif arm == 2:
            self.bus.write_byte_data(0x54, 0x0B, value)
            self.bus.write_byte_data(0x54, 0x0C, value)
            self.bus.write_byte_data(0x54, 0x0E, value)
            self.bus.write_byte_data(0x54, 0x10, value)
            self.bus.write_byte_data(0x54, 0x11, value)
            self.bus.write_byte_data(0x54, 0x12, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)
        elif arm == 3:
            self.bus.write_byte_data(0x54, 0x01, value)
            self.bus.write_byte_data(0x54, 0x02, value)
            self.bus.write_byte_data(0x54, 0x03, value)
            self.bus.write_byte_data(0x54, 0x04, value)
            self.bus.write_byte_data(0x54, 0x0F, value)
            self.bus.write_byte_data(0x54, 0x0D, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)
        else:
            print "Unknown number, expected only 1, 2 or 3"

    def arm1(self, value):
        self.bus.write_byte_data(0x54, 0x07, value)
        self.bus.write_byte_data(0x54, 0x08, value)
        self.bus.write_byte_data(0x54, 0x09, value)
        self.bus.write_byte_data(0x54, 0x06, value)
        self.bus.write_byte_data(0x54, 0x05, value)
        self.bus.write_byte_data(0x54, 0x0A, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def arm2(self, value):
        self.bus.write_byte_data(0x54, 0x0B, value)
        self.bus.write_byte_data(0x54, 0x0C, value)
        self.bus.write_byte_data(0x54, 0x0E, value)
        self.bus.write_byte_data(0x54, 0x10, value)
        self.bus.write_byte_data(0x54, 0x11, value)
        self.bus.write_byte_data(0x54, 0x12, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def arm3(self, value):
        self.bus.write_byte_data(0x54, 0x01, value)
        self.bus.write_byte_data(0x54, 0x02, value)
        self.bus.write_byte_data(0x54, 0x03, value)
        self.bus.write_byte_data(0x54, 0x04, value)
        self.bus.write_byte_data(0x54, 0x0F, value)
        self.bus.write_byte_data(0x54, 0x0D, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def colour(self, colour, value):
        if colour == 1 or colour == "white":
            self.bus.write_byte_data(0x54, 0x0A, value)
            self.bus.write_byte_data(0x54, 0x0B, value)
            self.bus.write_byte_data(0x54, 0x0D, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)

        elif colour == 2 or colour == "blue":
            self.bus.write_byte_data(0x54, 0x05, value)
            self.bus.write_byte_data(0x54, 0x0C, value)
            self.bus.write_byte_data(0x54, 0x0F, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)

        elif colour == 3 or colour == "green":
            self.bus.write_byte_data(0x54, 0x06, value)
            self.bus.write_byte_data(0x54, 0x04, value)
            self.bus.write_byte_data(0x54, 0x0E, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)

        elif colour == 4 or colour == "yellow":
            self.bus.write_byte_data(0x54, 0x09, value)
            self.bus.write_byte_data(0x54, 0x03, value)
            self.bus.write_byte_data(0x54, 0x10, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)

        elif colour == 5 or colour == "orange":
            self.bus.write_byte_data(0x54, 0x08, value)
            self.bus.write_byte_data(0x54, 0x02, value)
            self.bus.write_byte_data(0x54, 0x11, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)
        elif colour == 6 or colour == "red":
            self.bus.write_byte_data(0x54, 0x07, value)
            self.bus.write_byte_data(0x54, 0x01, value)
            self.bus.write_byte_data(0x54, 0x12, value)
            self.bus.write_byte_data(0x54, 0x16, 0xFF)
        else:
            print "Only colours 1 - 6 or color names are allowed"

    def led(self, led, value):
        leds = [
            "0x00", "0x07", "0x08", "0x09", "0x06", "0x05", "0x0A", "0x12", "0x11",
            "0x10", "0x0E", "0x0C", "0x0B", "0x01", "0x02", "0x03", "0x04", "0x0F", "0x0D"]
        self.bus.write_byte_data(0x54, int(leds[led], 16), value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led1(self, value):
        self.bus.write_byte_data(0x54, 0x07, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led2(self, value):
        self.bus.write_byte_data(0x54, 0x08, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led3(self, value):
        self.bus.write_byte_data(0x54, 0x09, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led4(self, value):
        self.bus.write_byte_data(0x54, 0x06, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led5(self, value):
        self.bus.write_byte_data(0x54, 0x05, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led6(self, value):
        self.bus.write_byte_data(0x54, 0x0A, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led7(self, value):
        self.bus.write_byte_data(0x54, 0x12, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led8(self, value):
        self.bus.write_byte_data(0x54, 0x11, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led9(self, value):
        self.bus.write_byte_data(0x54, 0x10, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led10(self, value):
        self.bus.write_byte_data(0x54, 0x0E, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led11(self, value):
        self.bus.write_byte_data(0x54, 0x0C, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led12(self, value):
        self.bus.write_byte_data(0x54, 0x0B, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led13(self, value):
        self.bus.write_byte_data(0x54, 0x01, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led14(self, value):
        self.bus.write_byte_data(0x54, 0x02, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led15(self, value):
        self.bus.write_byte_data(0x54, 0x03, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led16(self, value):
        self.bus.write_byte_data(0x54, 0x04, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led17(self, value):
        self.bus.write_byte_data(0x54, 0x0F, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)

    def led18(self, value):
        self.bus.write_byte_data(0x54, 0x0D, value)
        self.bus.write_byte_data(0x54, 0x16, 0xFF)
Exemplo n.º 37
0
class ADS1x15(object):

    # IC Identifiers
    __IC_ADS1015                      = 0x00
    __IC_ADS1115                      = 0x01

    # Pointer Register
    __ADS1015_REG_POINTER_MASK        = 0x03
    __ADS1015_REG_POINTER_CONVERT     = 0x00
    __ADS1015_REG_POINTER_CONFIG      = 0x01
    __ADS1015_REG_POINTER_LOWTHRESH   = 0x02
    __ADS1015_REG_POINTER_HITHRESH    = 0x03

    # Config Register
    __ADS1015_REG_CONFIG_OS_MASK      = 0x8000
    __ADS1015_REG_CONFIG_OS_SINGLE    = 0x8000  # Write: Set to start a single-conversion
    __ADS1015_REG_CONFIG_OS_BUSY      = 0x0000  # Read: Bit = 0 when conversion is in progress
    __ADS1015_REG_CONFIG_OS_NOTBUSY   = 0x8000  # Read: Bit = 1 when device is not performing a conversion

    __ADS1015_REG_CONFIG_MUX_MASK     = 0x7000
    __ADS1015_REG_CONFIG_MUX_DIFF_0_1 = 0x0000  # Differential P = AIN0, N = AIN1 (default)
    __ADS1015_REG_CONFIG_MUX_DIFF_0_3 = 0x1000  # Differential P = AIN0, N = AIN3
    __ADS1015_REG_CONFIG_MUX_DIFF_1_3 = 0x2000  # Differential P = AIN1, N = AIN3
    __ADS1015_REG_CONFIG_MUX_DIFF_2_3 = 0x3000  # Differential P = AIN2, N = AIN3
    __ADS1015_REG_CONFIG_MUX_SINGLE_0 = 0x4000  # Single-ended AIN0
    __ADS1015_REG_CONFIG_MUX_SINGLE_1 = 0x5000  # Single-ended AIN1
    __ADS1015_REG_CONFIG_MUX_SINGLE_2 = 0x6000  # Single-ended AIN2
    __ADS1015_REG_CONFIG_MUX_SINGLE_3 = 0x7000  # Single-ended AIN3

    __ADS1015_REG_CONFIG_PGA_MASK     = 0x0E00
    __ADS1015_REG_CONFIG_PGA_6_144V   = 0x0000  # +/-6.144V range
    __ADS1015_REG_CONFIG_PGA_4_096V   = 0x0200  # +/-4.096V range
    __ADS1015_REG_CONFIG_PGA_2_048V   = 0x0400  # +/-2.048V range (default)
    __ADS1015_REG_CONFIG_PGA_1_024V   = 0x0600  # +/-1.024V range
    __ADS1015_REG_CONFIG_PGA_0_512V   = 0x0800  # +/-0.512V range
    __ADS1015_REG_CONFIG_PGA_0_256V   = 0x0A00  # +/-0.256V range

    __ADS1015_REG_CONFIG_MODE_MASK    = 0x0100
    __ADS1015_REG_CONFIG_MODE_CONTIN  = 0x0000  # Continuous conversion mode
    __ADS1015_REG_CONFIG_MODE_SINGLE  = 0x0100  # Power-down single-shot mode (default)

    __ADS1015_REG_CONFIG_DR_MASK      = 0x00E0  
    __ADS1015_REG_CONFIG_DR_128SPS    = 0x0000  # 128 samples per second
    __ADS1015_REG_CONFIG_DR_250SPS    = 0x0020  # 250 samples per second
    __ADS1015_REG_CONFIG_DR_490SPS    = 0x0040  # 490 samples per second
    __ADS1015_REG_CONFIG_DR_920SPS    = 0x0060  # 920 samples per second
    __ADS1015_REG_CONFIG_DR_1600SPS   = 0x0080  # 1600 samples per second (default)
    __ADS1015_REG_CONFIG_DR_2400SPS   = 0x00A0  # 2400 samples per second
    __ADS1015_REG_CONFIG_DR_3300SPS   = 0x00C0  # 3300 samples per second (also 0x00E0)

    __ADS1115_REG_CONFIG_DR_8SPS      = 0x0000  # 8 samples per second
    __ADS1115_REG_CONFIG_DR_16SPS     = 0x0020  # 16 samples per second
    __ADS1115_REG_CONFIG_DR_32SPS     = 0x0040  # 32 samples per second
    __ADS1115_REG_CONFIG_DR_64SPS     = 0x0060  # 64 samples per second
    __ADS1115_REG_CONFIG_DR_128SPS    = 0x0080  # 128 samples per second
    __ADS1115_REG_CONFIG_DR_250SPS    = 0x00A0  # 250 samples per second (default)
    __ADS1115_REG_CONFIG_DR_475SPS    = 0x00C0  # 475 samples per second
    __ADS1115_REG_CONFIG_DR_860SPS    = 0x00E0  # 860 samples per second

    __ADS1015_REG_CONFIG_CMODE_MASK   = 0x0010
    __ADS1015_REG_CONFIG_CMODE_TRAD   = 0x0000  # Traditional comparator with hysteresis (default)
    __ADS1015_REG_CONFIG_CMODE_WINDOW = 0x0010  # Window comparator

    __ADS1015_REG_CONFIG_CPOL_MASK    = 0x0008
    __ADS1015_REG_CONFIG_CPOL_ACTVLOW = 0x0000  # ALERT/RDY pin is low when active (default)
    __ADS1015_REG_CONFIG_CPOL_ACTVHI  = 0x0008  # ALERT/RDY pin is high when active

    __ADS1015_REG_CONFIG_CLAT_MASK    = 0x0004  # Determines if ALERT/RDY pin latches once asserted
    __ADS1015_REG_CONFIG_CLAT_NONLAT  = 0x0000  # Non-latching comparator (default)
    __ADS1015_REG_CONFIG_CLAT_LATCH   = 0x0004  # Latching comparator

    __ADS1015_REG_CONFIG_CQUE_MASK    = 0x0003
    __ADS1015_REG_CONFIG_CQUE_1CONV   = 0x0000  # Assert ALERT/RDY after one conversions
    __ADS1015_REG_CONFIG_CQUE_2CONV   = 0x0001  # Assert ALERT/RDY after two conversions
    __ADS1015_REG_CONFIG_CQUE_4CONV   = 0x0002  # Assert ALERT/RDY after four conversions
    __ADS1015_REG_CONFIG_CQUE_NONE    = 0x0003  # Disable the comparator and put ALERT/RDY in high state (default)


    # Dictionaries with the sampling speed values
    # These simplify and clean the code (avoid the abuse of if/elif/else clauses)
    spsADS1115 = {
    8:__ADS1115_REG_CONFIG_DR_8SPS,
    16:__ADS1115_REG_CONFIG_DR_16SPS,
    32:__ADS1115_REG_CONFIG_DR_32SPS,
    64:__ADS1115_REG_CONFIG_DR_64SPS,
    128:__ADS1115_REG_CONFIG_DR_128SPS,
    250:__ADS1115_REG_CONFIG_DR_250SPS,
    475:__ADS1115_REG_CONFIG_DR_475SPS,
    860:__ADS1115_REG_CONFIG_DR_860SPS
    }    
    spsADS1015 = {
    128:__ADS1015_REG_CONFIG_DR_128SPS,
    250:__ADS1015_REG_CONFIG_DR_250SPS,
    490:__ADS1015_REG_CONFIG_DR_490SPS,
    920:__ADS1015_REG_CONFIG_DR_920SPS,
    1600:__ADS1015_REG_CONFIG_DR_1600SPS,
    2400:__ADS1015_REG_CONFIG_DR_2400SPS,
    3300:__ADS1015_REG_CONFIG_DR_3300SPS
    }
    # Dictionariy with the programable gains
    pgaADS1x15 = {
    6144:__ADS1015_REG_CONFIG_PGA_6_144V,
    4096:__ADS1015_REG_CONFIG_PGA_4_096V,
    2048:__ADS1015_REG_CONFIG_PGA_2_048V,
    1024:__ADS1015_REG_CONFIG_PGA_1_024V,
    512:__ADS1015_REG_CONFIG_PGA_0_512V,
    256:__ADS1015_REG_CONFIG_PGA_0_256V
    }  

    def __init__(self, busId, slaveAddr=0x48, ic=__IC_ADS1115, debug=True):
        """Initializes I2C connection object with the ADX1x15. Note that the default address
         is 0x48 and the default device is the ADS1115. """
        self.__i2c = SMBus(busId) # initializes I2C connection on /dev/i2c-<busID>
        self.__slave = slaveAddr # sets the address of the I2C slave device (the ADS1115)

        # Make sure the IC specified is valid
        if ((ic < self.__IC_ADS1015) | (ic > self.__IC_ADS1115)):
          if (self.debug):
            print "ADS1x15: Invalid IC specfied: %h" % ic
          return -1
        else:
          self.ic = ic
            
        # Set pga value, so that getLastConversionResult() can use it,
        # any function that accepts a pga value must update this.
        self.pga = 6144    

        # turns on debug print statements
        self.debug = debug

    def __del__(self):
        del(self.__i2c) # deletes I2C connection

    def readADCSingleEnded(self, channel=0, pga=6144, sps=250):
        """Gets a single-ended ADC reading from the specified channel in mV.
        The sample rate for this mode (single-shot) can be used to lower the noise
        (low sps) or to lower the power consumption (high sps) by duty cycling,
        see datasheet page 14 for more info.
        The pga must be given in mV, see page 13 for the supported values."""
        
        # With invalid channel return -1
        if (channel > 3):
            if (self.debug):
                print "ADS1x15: Invalid channel specified: %d" % channel
            return -1
        
        # Disable comparator, Non-latching, Alert/Rdy active low
        # traditional comparator, single-shot mode
        config = self.__ADS1015_REG_CONFIG_CQUE_NONE    | \
                 self.__ADS1015_REG_CONFIG_CLAT_NONLAT  | \
                 self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
                 self.__ADS1015_REG_CONFIG_CMODE_TRAD   | \
                 self.__ADS1015_REG_CONFIG_MODE_SINGLE    

        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)

        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga

        # Set the channel to be converted
        if channel == 3:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
        elif channel == 2:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
        elif channel == 1:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
        else:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0

        # Set 'start single-conversion' bit
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE

        # Write config register to the ADC
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)

        # Wait for the ADC conversion to complete
        # The minimum delay depends on the sps: delay >= 1/sps
        # We add 0.1ms to be sure
        delay = 1.0/sps+0.0001
        time.sleep(delay)

        # Read the conversion results
        result = self.__i2c.read_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONVERT, 2)
        if (self.ic == self.__IC_ADS1015):
            # Shift right 4 bits for the 12-bit ADS1015 and convert to mV
            return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
        else:
            # Return a mV value for the ADS1115
            # (Take signed values into account as well)
            val = (result[0] << 8) | (result[1])
            if val > 0x7FFF:
                return (val - 0xFFFF)*pga/32768.0
            else:
                return ( (result[0] << 8) | (result[1]) )*pga/32768.0
    
    def readADCDifferential(self, chP=0, chN=1, pga=6144, sps=250):
        """Gets a differential ADC reading from channels chP and chN in mV.
        The sample rate for this mode (single-shot) can be used to lower the noise
        (low sps) or to lower the power consumption (high sps) by duty cycling,
        see data sheet page 14 for more info.
        The pga must be given in mV, see page 13 for the supported values."""
        
        # Disable comparator, Non-latching, Alert/Rdy active low
        # traditional comparator, single-shot mode    
        config = self.__ADS1015_REG_CONFIG_CQUE_NONE    | \
                 self.__ADS1015_REG_CONFIG_CLAT_NONLAT  | \
                 self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
                 self.__ADS1015_REG_CONFIG_CMODE_TRAD   | \
                 self.__ADS1015_REG_CONFIG_MODE_SINGLE  
        
        # Set channels
        if ( (chP == 0) & (chN == 1) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
        elif ( (chP == 0) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
        elif ( (chP == 2) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
        elif ( (chP == 1) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3  
        else:
            if (self.debug):
                print "ADS1x15: Invalid channels specified: %d, %d" % (chP, chN)
        return -1
             
        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init()) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
      
        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga

        # Set 'start single-conversion' bit
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE

        # Write config register to the ADC
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)

        # Wait for the ADC conversion to complete
        # The minimum delay depends on the sps: delay >= 1/sps
        # We add 0.1ms to be sure
        delay = 1.0/sps+0.0001
        time.sleep(delay)

        # Read the conversion results
        result = self.__i2c.read_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONVERT, 2) # TODO: self.__i2c.read_i2c_block_data(self.address, reg, length) # consider making wrapper
        if (self.ic == self.__IC_ADS1015):
            # Shift right 4 bits for the 12-bit ADS1015 and convert to mV
            val = ((result[0] << 8) | (result[1] & 0xFF)) >> 4
        # (Take signed values into account as well)
        if val >> 11:
            val = val - 0xfff
            return val*pga/2048.0
        else:
            # Return a mV value for the ADS1115
            # (Take signed values into account as well)
            val = (result[0] << 8) | (result[1])
            if val > 0x7FFF:
                return (val - 0xFFFF)*pga/32768.0
            else:
                return ( (result[0] << 8) | (result[1]) )*pga/32768.0
  
    def startContinuousConversion(self, channel=0, pga=6144, sps=250): 
        """Starts the continuous conversion mode and returns the first ADC reading
        in mV from the specified channel.
        The sps controls the sample rate.
        The pga must be given in mV, see datasheet page 13 for the supported values.
        Use getLastConversionResults() to read the next values and
        stopContinuousConversion() to stop converting."""
        
        # Default to channel 0 with invalid channel, or return -1?
        if (channel > 3):
            if (self.debug):
                print "ADS1x15: Invalid channel specified: %d" % channel
            return -1
        
        # Disable comparator, Non-latching, Alert/Rdy active low
        # traditional comparator, continuous mode
        # The last flag is the only change we need, page 11 datasheet
        config = self.__ADS1015_REG_CONFIG_CQUE_NONE    | \
                 self.__ADS1015_REG_CONFIG_CLAT_NONLAT  | \
                 self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
                 self.__ADS1015_REG_CONFIG_CMODE_TRAD   | \
                 self.__ADS1015_REG_CONFIG_MODE_CONTIN    

        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init()) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
      
        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga 
        
        # Set the channel to be converted
        if channel == 3:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
        elif channel == 2:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
        elif channel == 1:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
        else:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0    
      
        # Set 'start single-conversion' bit to begin conversions
        # No need to change this for continuous mode!
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE

        # Write config register to the ADC
        # Once we write the ADC will convert continously
        # we can read the next values using getLastConversionResult
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)

        # Wait for the ADC conversion to complete
        # The minimum delay depends on the sps: delay >= 1/sps
        # We add 0.5ms to be sure
        delay = 1.0/sps+0.0005
        time.sleep(delay)
      
        # Read the conversion results
        result = self.__i2c.read_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONVERT, 2)
        if (self.ic == self.__IC_ADS1015):
            # Shift right 4 bits for the 12-bit ADS1015 and convert to mV
            return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
        else:
            # Return a mV value for the ADS1115
            # (Take signed values into account as well)
            val = (result[0] << 8) | (result[1])
            if val > 0x7FFF:
                return (val - 0xFFFF)*pga/32768.0
            else:
                return ( (result[0] << 8) | (result[1]) )*pga/32768.0  

    def startContinuousDifferentialConversion(self, chP=0, chN=1, pga=6144, sps=250): 
        """Starts the continuous differential conversion mode and returns the first ADC reading
        in mV as the difference from the specified channels.
        The sps controls the sample rate.
        The pga must be given in mV, see datasheet page 13 for the supported values.
        Use getLastConversionResults() to read the next values and
        stopContinuousConversion() to stop converting."""
        
        # Disable comparator, Non-latching, Alert/Rdy active low
        # traditional comparator, continuous mode
        # The last flag is the only change we need, page 11 datasheet
        config = self.__ADS1015_REG_CONFIG_CQUE_NONE    | \
                 self.__ADS1015_REG_CONFIG_CLAT_NONLAT  | \
                 self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW | \
                 self.__ADS1015_REG_CONFIG_CMODE_TRAD   | \
                 self.__ADS1015_REG_CONFIG_MODE_CONTIN    
      
        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init()) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)
      
        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % sps     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga 
        
        # Set channels
        if ( (chP == 0) & (chN == 1) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
        elif ( (chP == 0) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
        elif ( (chP == 2) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
        elif ( (chP == 1) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3  
        else:
            if (self.debug):
                print "ADS1x15: Invalid channels specified: %d, %d" % (chP, chN)
        return -1  
        
        # Set 'start single-conversion' bit to begin conversions
        # No need to change this for continuous mode!
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
      
        # Write config register to the ADC
        # Once we write the ADC will convert continously
        # we can read the next values using getLastConversionResult
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)
      
        # Wait for the ADC conversion to complete
        # The minimum delay depends on the sps: delay >= 1/sps
        # We add 0.5ms to be sure
        delay = 1.0/sps+0.0005
        time.sleep(delay)
      
        # Read the conversion results
        result = self.__i2c.read_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONVERT, 2)
        if (self.ic == self.__IC_ADS1015):
            # Shift right 4 bits for the 12-bit ADS1015 and convert to mV
            return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*pga/2048.0
        else:
            # Return a mV value for the ADS1115
            # (Take signed values into account as well)
            val = (result[0] << 8) | (result[1])
            if val > 0x7FFF:
                return (val - 0xFFFF)*pga/32768.0
            else:
                return ( (result[0] << 8) | (result[1]) )*pga/32768.0  

    def stopContinuousConversion(self):
        """Stops the ADC's conversions when in continuous mode
        and resets the configuration to its default value."""
        # Write the default config register to the ADC
        # Once we write, the ADC will do a single conversion and 
        # enter power-off mode.
        config = 0x8583 # Page 18 datasheet.
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)    
        return True

    def getLastConversionResults(self):
        """Returns the last ADC conversion result in mV"""
        # Read the conversion results
        result = self.__i2c.read_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONVERT, 2)
        if (self.ic == self.__IC_ADS1015):
            # Shift right 4 bits for the 12-bit ADS1015 and convert to mV
            return ( ((result[0] << 8) | (result[1] & 0xFF)) >> 4 )*self.pga/2048.0
        else:
            # Return a mV value for the ADS1115
            # (Take signed values into account as well)
            val = (result[0] << 8) | (result[1])
            if val > 0x7FFF:
                return (val - 0xFFFF)*self.pga/32768.0
            else:
                return ( (result[0] << 8) | (result[1]) )*self.pga/32768.0  
    
    
    def startSingleEndedComparator(self, channel, thresholdHigh, thresholdLow, pga=6144, sps=250, activeLow=True, traditionalMode=True, latching=False, numReadings=1):
        """Starts the comparator mode on the specified channel, see datasheet pg. 15.
        In traditional mode it alerts (ALERT pin will go low)  when voltage exceeds 
        thresholdHigh until it falls below thresholdLow (both given in mV).
        In window mode (traditionalMode=False) it alerts when voltage doesn't lie
        between both thresholds.
        In latching mode the alert will continue until the conversion value is read.
        numReadings controls how many readings are necessary to trigger an alert: 1, 2 or 4.
        Use getLastConversionResults() to read the current value  (which may differ
        from the one that triggered the alert) and clear the alert pin in latching mode.
        This function starts the continuous conversion mode.  The sps controls
        the sample rate and the pga the gain, see datasheet page 13."""
        
        # With invalid channel return -1
        if (channel > 3):
            if (self.debug):
                print "ADS1x15: Invalid channel specified: %d" % channel
            return -1
        
        # Continuous mode
        config = self.__ADS1015_REG_CONFIG_MODE_CONTIN     
        
        if (activeLow==False):
            config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVHI
        else:
            config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW
          
        if (traditionalMode==False):
            config |= self.__ADS1015_REG_CONFIG_CMODE_WINDOW
        else:
            config |= self.__ADS1015_REG_CONFIG_CMODE_TRAD
          
        if (latching==True):
            config |= self.__ADS1015_REG_CONFIG_CLAT_LATCH
        else:
            config |= self.__ADS1015_REG_CONFIG_CLAT_NONLAT
          
        if (numReadings==4):
            config |= self.__ADS1015_REG_CONFIG_CQUE_4CONV
        elif (numReadings==2):
            config |= self.__ADS1015_REG_CONFIG_CQUE_2CONV
        else:
            config |= self.__ADS1015_REG_CONFIG_CQUE_1CONV
        
        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init()) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            if ( (sps not in self.spsADS1015) & self.debug):    
                print "ADS1x15: Invalid sps specified: %d, using 1600sps" % sps       
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid sps specified: %d, using 250sps" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)

        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % pga     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga
        
        # Set the channel to be converted
        if channel == 3:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_3
        elif channel == 2:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_2
        elif channel == 1:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_1
        else:
            config |= self.__ADS1015_REG_CONFIG_MUX_SINGLE_0

        # Set 'start single-conversion' bit to begin conversions
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
        
        # Write threshold high and low registers to the ADC
        # V_digital = (2^(n-1)-1)/pga*V_analog
        if (self.ic == self.__IC_ADS1015):
            thresholdHighWORD = int(thresholdHigh*(2048.0/pga))
        else:
            thresholdHighWORD = int(thresholdHigh*(32767.0/pga))
        bytes = [(thresholdHighWORD >> 8) & 0xFF, thresholdHighWORD & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_HITHRESH, bytes) 
      
        if (self.ic == self.__IC_ADS1015):
            thresholdLowWORD = int(thresholdLow*(2048.0/pga))
        else:
            thresholdLowWORD = int(thresholdLow*(32767.0/pga))    
        bytes = [(thresholdLowWORD >> 8) & 0xFF, thresholdLowWORD & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_LOWTHRESH, bytes)     

        # Write config register to the ADC
        # Once we write the ADC will convert continously and alert when things happen,
        # we can read the converted values using getLastConversionResult
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes) # TODO: replace "writeList"... self.__i2c.write_i2c_block_data(self.address, reg, list)

    def startDifferentialComparator(self, chP, chN, thresholdHigh, thresholdLow, pga=6144, sps=250, activeLow=True, traditionalMode=True, latching=False, numReadings=1):
        """Starts the comparator mode on the specified channel, see datasheet pg. 15.
        In traditional mode it alerts (ALERT pin will go low)  when voltage exceeds 
        thresholdHigh until it falls below thresholdLow (both given in mV).
        In window mode (traditionalMode=False) it alerts when voltage doesn't lie
        between both thresholds.
        In latching mode the alert will continue until the conversion value is read.
        numReadings controls how many readings are necessary to trigger an alert: 1, 2 or 4.
        Use getLastConversionResults() to read the current value  (which may differ
        from the one that triggered the alert) and clear the alert pin in latching mode.
        This function starts the continuous conversion mode.  The sps controls
        the sample rate and the pga the gain, see datasheet page 13."""

        # Continuous mode
        config = self.__ADS1015_REG_CONFIG_MODE_CONTIN     
        
        if (activeLow==False):
            config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVHI
        else:
            config |= self.__ADS1015_REG_CONFIG_CPOL_ACTVLOW
          
        if (traditionalMode==False):
            config |= self.__ADS1015_REG_CONFIG_CMODE_WINDOW
        else:
            config |= self.__ADS1015_REG_CONFIG_CMODE_TRAD
          
        if (latching==True):
            config |= self.__ADS1015_REG_CONFIG_CLAT_LATCH
        else:
            config |= self.__ADS1015_REG_CONFIG_CLAT_NONLAT
          
        if (numReadings==4):
            config |= self.__ADS1015_REG_CONFIG_CQUE_4CONV
        elif (numReadings==2):
            config |= self.__ADS1015_REG_CONFIG_CQUE_2CONV
        else:
            config |= self.__ADS1015_REG_CONFIG_CQUE_1CONV
        
        # Set sample per seconds, defaults to 250sps
        # If sps is in the dictionary (defined in init()) it returns the value of the constant
        # othewise it returns the value for 250sps. This saves a lot of if/elif/else code!
        if (self.ic == self.__IC_ADS1015):
            if ( (sps not in self.spsADS1015) & self.debug):    
                print "ADS1x15: Invalid sps specified: %d, using 1600sps" % sps       
            config |= self.spsADS1015.setdefault(sps, self.__ADS1015_REG_CONFIG_DR_1600SPS)
        else:
            if ( (sps not in self.spsADS1115) & self.debug):    
                print "ADS1x15: Invalid sps specified: %d, using 250sps" % sps     
            config |= self.spsADS1115.setdefault(sps, self.__ADS1115_REG_CONFIG_DR_250SPS)

        # Set PGA/voltage range, defaults to +-6.144V
        if ( (pga not in self.pgaADS1x15) & self.debug):      
            print "ADS1x15: Invalid pga specified: %d, using 6144mV" % pga     
        config |= self.pgaADS1x15.setdefault(pga, self.__ADS1015_REG_CONFIG_PGA_6_144V)
        self.pga = pga
        
        # Set channels
        if ( (chP == 0) & (chN == 1) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_1
        elif ( (chP == 0) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_0_3
        elif ( (chP == 2) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_2_3
        elif ( (chP == 1) & (chN == 3) ):
            config |= self.__ADS1015_REG_CONFIG_MUX_DIFF_1_3  
        else:
            if (self.debug):
                print "ADS1x15: Invalid channels specified: %d, %d" % (chP, chN)
            return -1

        # Set 'start single-conversion' bit to begin conversions
        config |= self.__ADS1015_REG_CONFIG_OS_SINGLE
        
        # Write threshold high and low registers to the ADC
        # V_digital = (2^(n-1)-1)/pga*V_analog
        if (self.ic == self.__IC_ADS1015):
            thresholdHighWORD = int(thresholdHigh*(2048.0/pga))
        else:
            thresholdHighWORD = int(thresholdHigh*(32767.0/pga))
        bytes = [(thresholdHighWORD >> 8) & 0xFF, thresholdHighWORD & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_HITHRESH, bytes) 
      
        if (self.ic == self.__IC_ADS1015):
            thresholdLowWORD = int(thresholdLow*(2048.0/pga))
        else:
            thresholdLowWORD = int(thresholdLow*(32767.0/pga))    
        bytes = [(thresholdLowWORD >> 8) & 0xFF, thresholdLowWORD & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_LOWTHRESH, bytes)     

        # Write config register to the ADC
        # Once we write the ADC will convert continously and alert when things happen,
        # we can read the converted values using getLastConversionResult
        bytes = [(config >> 8) & 0xFF, config & 0xFF]
        self.__i2c.write_i2c_block_data(self.__slave, self.__ADS1015_REG_POINTER_CONFIG, bytes)
Exemplo n.º 38
0
 
#
# MAIN
#
readCoefficients()
 
#
# unpack to 10bits full scale
_mpl115a2_a0 = (float)( (a0_MSB<<8) | a0_LSB  ) / (2<<3)
_mpl115a2_b1 = (float)( (b1_MSB<<8) | b1_LSB  ) / (2<<13)
_mpl115a2_b2 = (float)( (b2_MSB<<8) | b2_LSB  ) / (2<<14)
_mpl115a2_c12 = (float)( (c12_MSB<<8) | (c12_LSB >>2) ) / (2<<13)
 
#
# send conversion command   
bus.write_i2c_block_data(MPL115A2_ADDRESS,MPL115A2_REGISTER_STARTCONVERSION,[0x12])
 
#   
# sleep until the conversion is certainly completed
time.sleep(0.5);
 
#
# pressure AGC units
pressure_MSB = bus.read_byte_data(MPL115A2_ADDRESS,MPL115A2_REGISTER_PRESSURE_MSB);
pressure_LSB = bus.read_byte_data(MPL115A2_ADDRESS,MPL115A2_REGISTER_PRESSURE_LSB);
 
#
# temperatture AGC units
temp_MSB = bus.read_byte_data(MPL115A2_ADDRESS,MPL115A2_REGISTER_TEMP_MSB+0);
temp_LSB = bus.read_byte_data(MPL115A2_ADDRESS,MPL115A2_REGISTER_TEMP_LSB+0);
 
Exemplo n.º 39
0
class Mpl3115A2(object):
    #I2C ADDRESS/BITS
    ADDRESS = (0x60)

    #REGISTERS
    REGISTER_STATUS = (0x00)
    REGISTER_STATUS_TDR = 0x02
    REGISTER_STATUS_PDR = 0x04
    REGISTER_STATUS_PTDR = 0x08

    REGISTER_PRESSURE_MSB = (0x01)
    REGISTER_PRESSURE_CSB = (0x02)
    REGISTER_PRESSURE_LSB = (0x03)

    REGISTER_TEMP_MSB = (0x04)
    REGISTER_TEMP_LSB = (0x05)

    REGISTER_DR_STATUS = (0x06)

    OUT_P_DELTA_MSB = (0x07)
    OUT_P_DELTA_CSB = (0x08)
    OUT_P_DELTA_LSB = (0x09)

    OUT_T_DELTA_MSB = (0x0A)
    OUT_T_DELTA_LSB = (0x0B)

    BAR_IN_MSB = (0x14)
    BAR_IN_LSB = (0x15)

    WHOAMI = (0x0C)

    #BITS

    PT_DATA_CFG = 0x13
    PT_DATA_CFG_TDEFE = 0x01
    PT_DATA_CFG_PDEFE = 0x02
    PT_DATA_CFG_DREM = 0x04

    CTRL_REG1 = (0x26)
    CTRL_REG1_SBYB = 0x01
    CTRL_REG1_OST = 0x02
    CTRL_REG1_RST = 0x04
    CTRL_REG1_OS1 = 0x00
    CTRL_REG1_OS2 = 0x08
    CTRL_REG1_OS4 = 0x10
    CTRL_REG1_OS8 = 0x18
    CTRL_REG1_OS16 = 0x20
    CTRL_REG1_OS32 = 0x28
    CTRL_REG1_OS64 = 0x30
    CTRL_REG1_OS128 = 0x38
    CTRL_REG1_RAW = 0x40
    CTRL_REG1_ALT = 0x80
    CTRL_REG1_BAR = 0x00
    CTRL_REG2 = (0x27)
    CTRL_REG3 = (0x28)
    CTRL_REG4 = (0x29)
    CTRL_REG5 = (0x2A)

    REGISTER_STARTCONVERSION = (0x12)

    def __init__(self):
        self.bus = SMBus(1)
        self.verify_device()
        self.initialize()

    def verify_device(self):
        whoami = self.bus.read_byte_data(self.ADDRESS, self.WHOAMI)
        if whoami != 0xc4:
            # 0xc4 is a default value, but it can be programmed to other
            # values.  Mine reports 0xee.
            print "Device not active: %x != %x"%(whoami,0xc4)
            return False
        return True

    def initialize(self):
        self.bus.write_byte_data(
            self.ADDRESS,
            self.CTRL_REG1,
            self.CTRL_REG1_SBYB |
            self.CTRL_REG1_OS128 |
            self.CTRL_REG1_ALT)

        self.bus.write_byte_data(
            self.ADDRESS,
            self.PT_DATA_CFG, 
            self.PT_DATA_CFG_TDEFE |
            self.PT_DATA_CFG_PDEFE |
            self.PT_DATA_CFG_DREM)

    def poll(self,flag=None):
        if flag is None:
            flag=self.REGISTER_STATUS_PDR
        sta = 0
        while not (sta & self.REGISTER_STATUS_PDR):
            sta = self.bus.read_byte_data(self.ADDRESS, self.REGISTER_STATUS)

    def altitude():
        self.bus.write_byte_data(
            self.ADDRESS,
            self.CTRL_REG1, 
            self.CTRL_REG1_SBYB |
            self.CTRL_REG1_OS128 |
            self.CTRL_REG1_ALT)

        self.poll()

        msb, csb, lsb = self.bus.read_i2c_block_data(self.ADDRESS,
                                                     self.REGISTER_PRESSURE_MSB,3)
        alt = ((msb<<24) | (csb<<16) | (lsb<<8)) / 65536.

        # correct sign
        if alt > (1<<15):
            alt -= 1<<16

        return alt

    def temperature(self):
        self.bus.write_byte_data(
            self.ADDRESS,
            self.CTRL_REG1,
            self.CTRL_REG1_SBYB |
            self.CTRL_REG1_OS128 |
            self.CTRL_REG1_BAR)
        self.poll()
        return self.read_temperature()
    
    def read_temperature(self):
        msb, lsb = self.bus.read_i2c_block_data(self.ADDRESS,
                                                self.REGISTER_TEMP_MSB,2)
        # 12 bit, 2s-complement in degrees C.
        return ( (msb<<8) | lsb) / 256.0 

    def pressure(self):
        self.bus.write_byte_data(
            self.ADDRESS,
            self.CTRL_REG1, 
            self.CTRL_REG1_SBYB |
            self.CTRL_REG1_OS128 |
            self.CTRL_REG1_BAR)

        self.poll()
        return self.read_pressure()
    
    def press_temp(self):
        self.bus.write_byte_data(
            self.ADDRESS,
            self.CTRL_REG1, 
            self.CTRL_REG1_SBYB |
            self.CTRL_REG1_OS128 |
            self.CTRL_REG1_BAR)

        self.poll(self.REGISTER_STATUS_PDR|self.REGISTER_STATUS_TDR)
        press=self.read_pressure()
        temp=self.read_temperature()
        return press,temp
    def read_pressure(self):
        msb, csb, lsb = self.bus.read_i2c_block_data(self.ADDRESS,
                                                     self.REGISTER_PRESSURE_MSB,3)
        return ((msb<<16) | (csb<<8) | lsb) / 64.

    def calibrate(self):
        pa = int(self.pressure()/2)
        self.bus.write_i2c_block_data(self.ADDRESS, 
                                      self.BAR_IN_MSB, 
                                      [pa>>8 & 0xff, pa & 0xff])
Exemplo n.º 40
0
class WeatherHat(threading.Thread):

  def __init__(self):
    if rpi.RPI_REVISION == 1:
      i2c_bus = 0
    else:
      i2c_bus = 1

    self.bus = SMBus(i2c_bus)
    self.bus.write_i2c_block_data(0x54, 0x00, [0x01])
    self.bus.write_byte_data(0x54, 0x13, 0xFF)
    self.bus.write_byte_data(0x54, 0x14, 0xFF)
    self.bus.write_byte_data(0x54, 0x15, 0xFF)

    self.sun1 = gpiozero.PWMLED(4)
    self.sun2 = gpiozero.PWMLED(17)
    self.sun3 = gpiozero.PWMLED(27)



  def update(self):
     self.bus.write_byte_data(0x54, 0x16, 0xFF)


  def cleanup(self):
    self.bus.write_i2c_block_data(0x54, 0x00, [0x00])


  def rain1(self, value):
    self.bus.write_byte_data(0x54, 0x12, value)
    self.update()

  def rain2(self, value):
    self.bus.write_byte_data(0x54, 0x11, value)
    self.update()

  def rain3(self, value):
    self.bus.write_byte_data(0x54, 0x10, value)
    self.update()

  def rain4(self, value):
    self.bus.write_byte_data(0x54, 0x04, value)
    self.update()

  def rain5(self, value):
    self.bus.write_byte_data(0x54, 0x02, value)
    self.update()

  def rain6(self, value):
    self.bus.write_byte_data(0x54, 0x01, value)
    self.update()

  def storm1(self, value):
    self.bus.write_byte_data(0x54, 0x05, value)
    self.update()

  def storm2(self, value):
    self.bus.write_byte_data(0x54, 0x08, value)
    self.update()

  def storm3(self, value):
    self.bus.write_byte_data(0x54, 0x0A, value)
    self.update()

  def storm4(self, value):
    self.bus.write_byte_data(0x54, 0x06, value)
    self.update()

  def storm5(self, value):
    self.bus.write_byte_data(0x54, 0x09, value)
    self.update()

  def storm6(self, value):
    self.bus.write_byte_data(0x54, 0x0B, value)
    self.update()

  def cloud1(self, value):
    self.bus.write_byte_data(0x54, 0x0F, value)
    self.update()

  def cloud2(self, value):
    self.bus.write_byte_data(0x54, 0x0D, value)
    self.update()

  def cloud3(self, value):
    self.bus.write_byte_data(0x54, 0x0E, value)
    self.update()

  def cloud4(self, value):
    self.bus.write_byte_data(0x54, 0x0C, value)
    self.update()

  def cloud5(self, value):
    self.bus.write_byte_data(0x54, 0x07, value)
    self.update()

  def cloud6(self, value):
    self.bus.write_byte_data(0x54, 0x03, value)
    self.update()

  def sunled(self, part, value):
    if ( part == 1 ):
      self.sun1.value = value
    elif ( part == 2 ):
      self.sun2.value = value
    else:
      self.sun3.value = value





  def rainrun(self):
    while self.rainrunning == 1:
      k = 70
      j = 20
      for i in range(100,1,-1):
        if j == 1:
          j = 80
        if k == 1:
          k = 90

        self.rain3(j)
        self.rain2(i)
        sleep(0.005)
        self.rain5(i)
        sleep(0.005)
        sleep(0.005)
        self.rain4(j)

        self.rain1(k)
        sleep(0.005)
        self.rain6(k)
        k = k-1
        j = j-1

      self.rain1(0)
      self.rain2(0)
      self.rain3(0)
      self.rain4(0)
      self.rain5(0)
      self.rain6(0)



  def raining(self,action):
    if action == "start":
      self.rainrunning = 1
      threading.Thread(target = self.rainrun).start()
    if action == "stop":
      self.rainrunning = 0






  def cloudrun(self):
    while self.cloudrunning == 1:
      k = 70
      j = 20
      for i in range(60,1,-1):
        if j == 1:
          j = 20
        if k == 1:
          k = 50

        self.cloud1(j)
        self.cloud2(i)
        sleep(0.005)
        self.cloud3(i)
        sleep(0.005)
        sleep(0.005)
        self.cloud4(j)

        self.cloud5(k)
        sleep(0.005)
        self.cloud6(k)
        k = k-1
        j = j-1
  
      self.cloud1(0)
      self.cloud2(0)
      self.cloud3(0)
      self.cloud4(0)
      self.cloud5(0)
      self.cloud6(0)



  def cloud(self,action):
    if action == "start":
      self.cloudrunning = 1
      threading.Thread(target = self.cloudrun).start()
    if action == "stop":
      self.cloudrunning = 0



  def stormrun(self):
    while self.stormrunning == 1:
      for i in range(255,1,-1):
        self.storm6(i)
        self.storm5(i-20)
        self.storm4(i-40)
        self.storm3(i-60)
        self.storm2(i-80)
        self.storm1(i-100)
        sleep(0.005)

      self.storm1(0)
      self.storm2(0)
      self.storm3(0)
      self.storm4(0)
      self.storm5(0)
      self.storm6(0)

  def storm(self,action):
    if action == "start":
      self.stormrunning = 1
      threading.Thread(target = self.stormrun).start()
    if action == "stop":
      self.stormrunning = 0




  def sunrun(self):
    while self.sunrunning == 1:

      for i in frange(0.4,0.2,-0.1):
        self.sunled(3,i)
        self.sunled(1,i*2)
        self.sunled(2,i*1.5)
        sleep(0.1)

      self.sunled(1,0.0)
      self.sunled(2,0.0)
      self.sunled(3,0.0)


  def sun(self,action):
    if action == "start":
      self.sunrunning = 1
      threading.Thread(target = self.sunrun).start()
    if action == "stop":
      self.sunrunning = 0



  def rainbow(self,action):
    if action == "start":
      panel.setPixelColor(0,Color(0,255,0))
      panel.setPixelColor(1,Color(50,255,0))
      panel.setPixelColor(2,Color(255,255,0))
      panel.setPixelColor(3,Color(255,0,0))
      panel.setPixelColor(4,Color(0,0,255))
      panel.setPixelColor(5,Color(0,255,50))
      panel.setPixelColor(6,Color(0,255,255))

      panel.show()

    if action == "stop":
      panel.setPixelColor(0,Color(0,0,0))
      panel.setPixelColor(1,Color(0,0,0))
      panel.setPixelColor(2,Color(0,0,0))
      panel.setPixelColor(3,Color(0,0,0))
      panel.setPixelColor(4,Color(0,0,0))
      panel.setPixelColor(5,Color(0,0,0))
      panel.setPixelColor(6,Color(0,0,0))

      panel.show()
Exemplo n.º 41
0
class PyGlow:
    def __init__(self, i2c_bus=1):
        self.bus = SMBus(i2c_bus)
        self.current = self._zerolist()

    def init(self):
        self.write_i2c(CMD_ENABLE_OUTPUT, 0x01)
        self.write_i2c(CMD_ENABLE_LEDS, [0xFF, 0xFF, 0xFF])
        self.all_off()

    def write_i2c(self, reg, value):
        if not isinstance(value, list):
            value = [value]
        self.bus.write_i2c_block_data(I2C_ADDR, reg, value)

    def update_leds(self, values):
        self.write_i2c(CMD_SET_PWM_VALUES, values)
        self.update()

    def update(self):
        self.bus.write_byte_data(I2C_ADDR, CMD_UPDATE, 0xFF)

    def set(self, leds, intensity=DEFAULT_INTENSITY):
        if not isinstance(leds, list):
            leds = [leds]
        for led in leds:
            self.bus.write_byte_data(I2C_ADDR, LED_ADDRS[led], intensity)

    def all_off(self):
        self.current = self._zerolist()
        self.update_leds(self.current)

    def turn_off(self, leds):
        self.set(leds, 0x00)
        self.update()

    def light(self, leds, intensity=DEFAULT_INTENSITY):
        if not isinstance(leds, list):
            leds = [leds]
        self.all_off()
        self.set(leds, intensity)
        self.update()

    def fade_in(self, leds, intensity=DEFAULT_INTENSITY,
                speed=DEFAULT_FADE_SPEED, step=DEFAULT_FADE_STEP):
        cur_inten = 0x00
        while cur_inten <= intensity:
            self.light(leds, cur_inten)
            cur_inten += step
            if cur_inten > 0xFF:
                break
            time.sleep(speed)

    def fade_out(self, leds, intensity=DEFAULT_INTENSITY,
                 speed=DEFAULT_FADE_SPEED, step=DEFAULT_FADE_STEP):
        while intensity >= 0x00:
            self.light(leds, intensity)
            intensity -= step
            if intensity < 0x00:
                self.turn_off(leds)
                break
            time.sleep(speed)

    def crossfade(self, leds_start, leds_end, intensity=DEFAULT_INTENSITY,
                  speed=DEFAULT_FADE_SPEED, step=DEFAULT_FADE_STEP):
        cur_inten_up = 0x00
        cur_inten_down = intensity
        while cur_inten_up < intensity:
            cur_inten_down -= step
            cur_inten_up += step
            if cur_inten_down <= 0x00:
                self.turn_off(leds_start)
                break
            if cur_inten_up >= 0xFF:
                self.set(leds_end, 0xFF)
                self.update()
                break
            self.set(leds_start, cur_inten_down)
            self.set(leds_end, cur_inten_up)
            self.update()
            time.sleep(speed)

    def _zerolist(self):
        return [0x00 for x in range(18)]
Exemplo n.º 42
0
        print "Microchip"
    else:
        print "Unknown"

def FindChip(jedec_id):
    for chip in FlashDevices:
        if (chip.jedec_id == jedec_id):
            return chip
    return None
# uint8_t GetManufacturerId(uint32_t jedec_id)
def GetManufacturerId(jedec_id):
    return jedec_id >> 16


print "Enter ISP?"
bus.write_i2c_block_data(0x4a,0x6f, [0x80])
    # uint32_t jedec_id = SPICommonCommand(E_CC_READ, 0x9f, 3, 0, 0);
print "Send SPI command"
jedec_id = SPICommonCommand(E_CC_READ, 0x9f, 3, 0, 0);
print jedec_id
#jedec_id=jedec_id[0]
    # printf("JEDEC ID: 0x%02x\n", jedec_id);
print "JEDEC ID: 0x{:02X}\n".format(jedec_id);
chip = FindChip(jedec_id);


if jedec_id == 15675411:
    print "flash matches!"
else:
    print "what is this flash chip?"
    exit(0)