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 HTU21D():
    """Class for accessing HTU21D sensors via I2C.

    Code taken from https://github.com/jasiek/HTU21D.

    Args:
        busno (int): The I2C bus (0 or 1, default is 1).
        address (byte): The I2C address of the sensor.
    """
    CMD_TRIG_TEMP_HM = 0xE3
    CMD_TRIG_HUMID_HM = 0xE5
    CMD_TRIG_TEMP_NHM = 0xF3
    CMD_TRIG_HUMID_NHM = 0xF5
    CMD_WRITE_USER_REG = 0xE6
    CMD_READ_USER_REG = 0xE7
    CMD_RESET = 0xFE

    def __init__(self, busno=1, address=config.SENSOR_ID_HUMIDITY_EXT):
        self.bus = SMBus(busno)
        self.i2c_address = address

    def read_temperature(self):
        self.reset()
        msb, lsb, crc = self.bus.read_i2c_block_data(
            self.i2c_address, self.CMD_TRIG_TEMP_HM, 3)
        return -46.85 + 175.72 * (msb * 256 + lsb) / 65536

    def read_humidity(self):
        self.reset()
        msb, lsb, crc = self.bus.read_i2c_block_data(
            self.i2c_address, self.CMD_TRIG_HUMID_HM, 3)
        return (-6 + 125 * (msb * 256 + lsb) / 65536.0) / 100.0

    def reset(self):
        self.bus.write_byte(self.i2c_address, self.CMD_RESET)
Exemplo n.º 4
0
class HTU21D:
    def __init__(self, busno):
        self.bus = SMBus(busno)

    def read_temperature(self):
        self.reset()
        msb, lsb, crc = self.bus.read_i2c_block_data(I2C_ADDR, CMD_TRIG_TEMP_HM, 3)
        return -46.85 + 175.72 * (msb * 256 + lsb) / 65536
     
    def read_humidity(self):
        self.reset()
        msb, lsb, crc = self.bus.read_i2c_block_data(I2C_ADDR, CMD_TRIG_HUMID_HM, 3)
        return -6 + 125 * (msb * 256 + lsb) / 65536.0

    def reset(self):
        self.bus.write_byte(I2C_ADDR, CMD_RESET)
Exemplo n.º 5
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]
def readMPL3155():
    # I2C Constants
    ADDR = 0x60
    CTRL_REG1 = 0x26
    PT_DATA_CFG = 0x13
    bus = SMBus(2)

    who_am_i = bus.read_byte_data(ADDR, 0x0C)
    print hex(who_am_i)
    if who_am_i != 0xc4:
        tfile = open('temp.txt', 'w')
        tfile.write("Barometer funktioniert nicht")
        tfile.close()
        exit(1)

    # Set oversample rate to 128
    setting = bus.read_byte_data(ADDR, CTRL_REG1)
    #newSetting = setting | 0x38
    newSetting = 0x38
    bus.write_byte_data(ADDR, CTRL_REG1, newSetting)

    # Enable event flags
    bus.write_byte_data(ADDR, PT_DATA_CFG, 0x07)

    # Toggel One Shot
    setting = bus.read_byte_data(ADDR, CTRL_REG1)
    if (setting & 0x02) == 0:
        bus.write_byte_data(ADDR, CTRL_REG1, (setting | 0x02))

    # Read sensor data
    print "Waiting for data..."
    status = bus.read_byte_data(ADDR,0x00)
    #while (status & 0x08) == 0:
    while (status & 0x06) == 0:
        #print bin(status)
        status = bus.read_byte_data(ADDR,0x00)
        time.sleep(1)

    print "Reading sensor data..."
    status = bus.read_byte_data(ADDR,0x00)
    p_data = bus.read_i2c_block_data(ADDR,0x01,3)
    t_data = bus.read_i2c_block_data(ADDR,0x04,2)

    p_msb = p_data[0]
    p_csb = p_data[1]
    p_lsb = p_data[2]
    t_msb = t_data[0]
    t_lsb = t_data[1]

    pressure = (p_msb << 10) | (p_csb << 2) | (p_lsb >> 6)
    p_decimal = ((p_lsb & 0x30) >> 4)/4.0

    celsius = t_msb + (t_lsb >> 4)/16.0

    tfile = open('temp.txt', 'w')
    tfile.write("Luftdruck "+str(pressure/100)+" Hektopascal. ")
    tfile.write("Temperatur "+str("{0:.1f}".format(celsius).replace('.',','))+" Grad Celsius")
    tfile.close()
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.º 8
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)
def getPressure():
    # I2C Constants
    ADDR = 0x60
    CTRL_REG1 = 0x26
    PT_DATA_CFG = 0x13
    bus = SMBus(1)

    who_am_i = bus.read_byte_data(ADDR, 0x0C)
    print hex(who_am_i)
    if who_am_i != 0xc4:
        print "Device not active."
        exit(1)

    # Set oversample rate to 128
    setting = bus.read_byte_data(ADDR, CTRL_REG1)
    newSetting = setting | 0x38
    bus.write_byte_data(ADDR, CTRL_REG1, newSetting)

    # Enable event flags
    bus.write_byte_data(ADDR, PT_DATA_CFG, 0x07)

    # Toggel One Shot
    setting = bus.read_byte_data(ADDR, CTRL_REG1)
    if (setting & 0x02) == 0:
        bus.write_byte_data(ADDR, CTRL_REG1, (setting | 0x02))
    status = -1;
    while (status & 0x08) == 0:
        status = bus.read_byte_data(ADDR,0x00)
        time.sleep(.5);

    print "Reading sensor data..."
    p_data = bus.read_i2c_block_data(ADDR,0x01,3)
    t_data = bus.read_i2c_block_data(ADDR,0x04,2)
    status = bus.read_byte_data(ADDR,0x00)
    print "status: "+bin(status)

    p_msb = p_data[0]
    p_csb = p_data[1]
    p_lsb = p_data[2]
    t_msb = t_data[0]
    t_lsb = t_data[1]

    pressure = (p_msb << 10) | (p_csb << 2) | (p_lsb >> 6)
    p_decimal = ((p_lsb & 0x30) >> 4)/4.0


    return pressure+p_decimal
Exemplo n.º 10
0
class TMP100:
    """ Class to read the onboard temperatur Sensor"""

    _SLAVE_ADDR = 0x49
    _CONFIG_REG = 0x01
    _TEMP_REG = 0x00
    # config register
    _CONFIG_REG_OS = 0x01
    _CONFIG_REG_RES_9B = 0x00
    _CONFIG_REG_RES_12B = 0x03
    _CONFIG_REG_TRIG_OS = 0x80
    def __init__(self,device_number = 1):
        """ """
        try:
            self.bus = SMBus(device_number)
        except Exception:
            raise i2cError()
        configList = [self._CONFIG_REG_OS, self._CONFIG_REG_RES_12B]
        self.configTMP100(configList)

    def configTMP100(self, list):
        """ Write list elements to tmp100#s configuration register"""
        reg = (list[1] << 5) + list[0]
        # write to config register
        self.bus.write_byte_data(self._SLAVE_ADDR,self._CONFIG_REG,reg)
        if DEBUG:
            # read config register back
            tmpReg = self.bus.read_byte_data(self._SLAVE_ADDR,self._CONFIG_REG)
            print(reg,tmpReg)

    def  getTemperature(self):
        """ Get temperature readings """
        # read first config register
        config = self.bus.read_byte_data(self._SLAVE_ADDR,self._CONFIG_REG)
        #trigger single shot
        newConfig = config + self._CONFIG_REG_TRIG_OS
        # write config register new value back
        self.bus.write_byte_data(self._SLAVE_ADDR,self._CONFIG_REG,newConfig)
        time.sleep(0.001) # wait a bit
        #read temperature register
        raw = self.bus.read_i2c_block_data(self._SLAVE_ADDR,self._TEMP_REG)[:2]
        val = ((raw[0] << 8) + raw[1]) >> 4

        #TODO: get resolution factor properly :)
        return val*0.0625
Exemplo n.º 11
0
def GetAlt():
    # get the altitude from the MPL3115a2 device
    print "GetAlt()"

    # device address and register addresses
    altAddress = 0x60
    ctrlReg1 = 0x26
    ptDataCfg = 0x13

    # values
    oversample128 = 0x38
    oneShot = 0x02
    altMode = 0x80

    bus = SMBus(1)
    for i in range(0, 5):
        whoAmI = bus.read_byte_data(altAddress, 0x0C)
        if whoAmI == 0xC4:
            break
        elif i == 4:
            sys.exit()
        else:
            time.sleep(0.5)
    bus.write_byte_data(altAddress, ptDataCfg, 0x07)

    oldSetting = bus.read_byte_data(altAddress, ctrlReg1)

    newSetting = oldSetting | oversample128 | oneShot | altMode

    bus.write_byte_data(altAddress, ctrlReg1, newSetting)

    status = bus.read_byte_data(altAddress, 0x00)
    while (status & 0x08) == 0:
        status = bus.read_byte_data(altAddress, 0x00)
        time.sleep(0.5)
    msb, csb, lsb = bus.read_i2c_block_data(altAddress, 0x01, 3)
    alt = ((msb << 24) | (csb << 16) | (lsb << 8)) / 65536.0
    if alt > (1 << 15):
        alt -= 1 << 16

    return alt
Exemplo n.º 12
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.º 13
0
buf = [0,0]

if __name__ == "__main__":
    main()
    
from smbus import SMBus
import time

i2cbus = SMBus(1)  # Create a new I2C bus
i2caddress = 0x18  # Address of keypad
RD_KEY_CMND          = 0x05
SET_KEY_VALUES_CMND  = 0x10

New_Key_Values = ['9','E','x','x','x',
                  '0','4','x','x','x',
                  'A','B','x','x','x',
                  'F','G','x','x','x',
                  'x','x','x','x','x'  
                  ]
New_Int_Values = [ord(str) for str in New_Key_Values]
print(New_Key_Values)
print(New_Int_Values)

i2cbus.write_i2c_block_data(i2caddress,SET_KEY_VALUES_CMND, New_Int_Values)

while 1:
    buf = i2cbus.read_i2c_block_data(i2caddress,RD_KEY_CMND,2)
    # duration = i2cbus.read_byte(i2caddress)
    #if buf[0] != 0:
    print(buf)
    time.sleep(1)
Exemplo n.º 14
0
# Toggel One Shot
setting = bus.read_byte_data(ADDR, CTRL_REG1)
if (setting & 0x02) == 0:
    bus.write_byte_data(ADDR, CTRL_REG1, (setting | 0x02))

# Read sensor data
print ("Esperando datos")
status = bus.read_byte_data(ADDR,0x00)
while (status & 0x08) == 0:
    #print bin(status)
    status = bus.read_byte_data(ADDR,0x00)
    time.sleep(0.5)

print ("Lectura de datos del sensor")
p_data = bus.read_i2c_block_data(ADDR,0x01,3)
t_data = bus.read_i2c_block_data(ADDR,0x04,2)
status = bus.read_byte_data(ADDR,0x00)
print ("estado:"+bin(status))

p_msb = p_data[0]
p_csb = p_data[1]
p_lsb = p_data[2]
t_msb = t_data[0]
t_lsb = t_data[1]

pressure = (p_msb << 10) | (p_csb << 2) | (p_lsb >> 6)
p_decimal = ((p_lsb & 0x30) >> 4)/4.0

celsius = t_msb + (t_lsb >> 4)/16.0-70
fahrenheit = (celsius * 9)/5 + 32
Exemplo n.º 15
0
class MS5611:

    __MS5611_ADDRESS_CSB_LOW = 0x76
    __MS5611_ADDRESS_CSB_HIGH = 0x77
    __MS5611_DEFAULT_ADDRESS = 0x77

    __MS5611_RA_ADC = 0x00
    __MS5611_RA_RESET = 0x1E

    __MS5611_RA_C0 = 0xA0
    __MS5611_RA_C1 = 0xA2
    __MS5611_RA_C2 = 0xA4
    __MS5611_RA_C3 = 0xA6
    __MS5611_RA_C4 = 0xA8
    __MS5611_RA_C5 = 0xAA
    __MS5611_RA_C6 = 0xAC
    __MS5611_RA_C7 = 0xAE

    __MS5611_RA_D1_OSR_256 = 0x40
    __MS5611_RA_D1_OSR_512 = 0x42
    __MS5611_RA_D1_OSR_1024 = 0x44
    __MS5611_RA_D1_OSR_2048 = 0x46
    __MS5611_RA_D1_OSR_4096 = 0x48

    __MS5611_RA_D2_OSR_256 = 0x50
    __MS5611_RA_D2_OSR_512 = 0x52
    __MS5611_RA_D2_OSR_1024 = 0x54
    __MS5611_RA_D2_OSR_2048 = 0x56
    __MS5611_RA_D2_OSR_4096 = 0x58

    def __init__(self, I2C_bus_number=1, address=0x77):
        self.bus = SMBus(I2C_bus_number)
        self.address = address
        self.C1 = 0
        self.C2 = 0
        self.C3 = 0
        self.C4 = 0
        self.C5 = 0
        self.C6 = 0
        self.D1 = 0
        self.D2 = 0
        self.TEMP = 0.0  # Calculated temperature
        self.PRES = 0.0  # Calculated Pressure

    def initialize(self):
        ## The MS6511 Sensor stores 6 values in the EPROM memory that we need in order to calculate the actual temperature and pressure
        ## These values are calculated/stored at the factory when the sensor is calibrated.
        ##      I probably could have used the read word function instead of the whole block, but I wanted to keep things consistent.
        C1 = self.bus.read_i2c_block_data(
            self.address, self.__MS5611_RA_C1)  #Pressure Sensitivity
        #time.sleep(0.05)
        C2 = self.bus.read_i2c_block_data(
            self.address, self.__MS5611_RA_C2)  #Pressure Offset
        #time.sleep(0.05)
        C3 = self.bus.read_i2c_block_data(
            self.address, self.__MS5611_RA_C3
        )  #Temperature coefficient of pressure sensitivity
        #time.sleep(0.05)
        C4 = self.bus.read_i2c_block_data(
            self.address,
            self.__MS5611_RA_C4)  #Temperature coefficient of pressure offset
        #time.sleep(0.05)
        C5 = self.bus.read_i2c_block_data(
            self.address, self.__MS5611_RA_C5)  #Reference temperature
        #time.sleep(0.05)
        C6 = self.bus.read_i2c_block_data(
            self.address,
            self.__MS5611_RA_C6)  #Temperature coefficient of the temperature

        ## Again here we are converting the 2 8bit packages into a single decimal
        self.C1 = C1[0] * 256.0 + C1[1]
        self.C2 = C2[0] * 256.0 + C2[1]
        self.C3 = C3[0] * 256.0 + C3[1]
        self.C4 = C4[0] * 256.0 + C4[1]
        self.C5 = C5[0] * 256.0 + C5[1]
        self.C6 = C6[0] * 256.0 + C6[1]

        self.update()

    def refreshPressure(self, OSR=__MS5611_RA_D1_OSR_4096):
        self.bus.write_byte(self.address, OSR)

    def refreshTemperature(self, OSR=__MS5611_RA_D2_OSR_4096):
        self.bus.write_byte(self.address, OSR)

    def readPressure(self):
        D1 = self.bus.read_i2c_block_data(self.address, self.__MS5611_RA_ADC)
        self.D1 = D1[0] * 65536 + D1[1] * 256.0 + D1[2]

    def readTemperature(self):
        D2 = self.bus.read_i2c_block_data(self.address, self.__MS5611_RA_ADC)
        self.D2 = D2[0] * 65536 + D2[1] * 256.0 + D2[2]

    def calculatePressureAndTemperature(self):
        dT = self.D2 - self.C5 * 2**8
        self.TEMP = 2000 + dT * self.C6 / 2**23

        OFF = self.C2 * 2**16 + (self.C4 * dT) / 2**7
        SENS = self.C1 * 2**15 + (self.C3 * dT) / 2**8

        if (self.TEMP >= 2000):
            T2 = 0
            OFF2 = 0
            SENS2 = 0
        elif (self.TEMP < 2000):
            T2 = dT * dT / 2**31
            OFF2 = 5 * ((self.TEMP - 2000)**2) / 2
            SENS2 = OFF2 / 2
        elif (self.TEMP < -1500):
            OFF2 = OFF2 + 7 * ((self.TEMP + 1500)**2)
            SENS2 = SENS2 + 11 * (self.TEMP + 1500)**2 / 2

        self.TEMP = self.TEMP - T2
        OFF = OFF - OFF2
        SENS = SENS - SENS2

        self.PRES = (self.D1 * SENS / 2**21 - OFF) / 2**15

        self.TEMP = self.TEMP / 100  # Temperature updated
        self.PRES = self.PRES / 100  # Pressure updated

    def returnPressure(self):
        return self.PRES

    def returnTemperature(self):
        return self.TEMP

    def update(self):
        self.refreshPressure()
        time.sleep(0.01)  # Waiting for pressure data ready
        self.readPressure()

        self.refreshTemperature()
        time.sleep(0.01)  # Waiting for temperature data ready
        self.readTemperature()

        self.calculatePressureAndTemperature()
Exemplo n.º 16
0
addr = 0x20  # I2C Address of MCP23017
irqPin = 26  # IRQ pin for MCP23017

os.system("sudo modprobe uinput")

ui = UInput({e.EV_KEY: key}, name="retrogame", bustype=e.BUS_USB)
bus = SMBus(3)
IODIR = 0x00
IOCON = 0x05
INTCAP = 0x08

# Initial MCP23008 config:
bus.write_byte_data(addr, IOCON, 0x44)  # seq, OD IRQ

# Read/modify/write remaining MCP23008 config:
cfg = bus.read_i2c_block_data(addr, IODIR, 7)
cfg[0] = 0xF  # Input bits
cfg[1] = 0x0  # Polarity
cfg[2] = 0xF  # Interrupt pins
cfg[6] = 0xF  # Pull-ups

bus.write_i2c_block_data(addr, IODIR, cfg)

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


# Callback for MCP23017 interrupt request
def mcp_irq(pin):
Exemplo n.º 17
0
class AM4096:
    """
    Class of the AM4096
    """
    eeprom_write_delay = 0.025 #in datasheet: at least 20 ms
    #self.configuration = {'Pdint','AGCdis','Slowint','Pdtr','Pdie','Reg35','Adr','Abridis','Bufsel','Monsel','Sign','Zin','Nfil','Daa','Hist','Dact','Dac','SSIcfg','Sth','UVW','Res','SRCH','Rpos','Apos','Weh','Wel','Thof','Tho'}

    def __init__(self , bus , Name = None , address = None):
        """ init the am4096 class"""
        self.bus = SMBus(bus)
        self.address = address
        self.busaddr= bus
        self.configuration = {}
        self.devices=[]
        self.i2c_repeated_start_condition = self.check_start_condition()
    def get_settings(self, stored = True):
        configuration = {}
        reg_addr= 0 if stored else 48
        row = self.read_memory(reg_addr)
        configuration['Pdint']= int((row[0] >> 7) & 0x01)
        configuration['AGCdis']= int((row[0] >> 6) & 0x01)
        configuration['Slowint']= int((row[0] >> 4) & 0x01)
        configuration['Pdtr']= int((row[0] >> 2) & 0x03)
        configuration['Pdie']= int((row[0] >> 1) & 0x01)
        configuration['Reg35']= int(row[0] & 0x01)
        configuration['Addr']= int(row[1] & 0x7F)

        row = self.read_memory(reg_addr+1)
        configuration['Abridis']= int((row[0] >> 7) & 0x01)
        configuration['Bufsel']= int((row[0] >> 6) & 0x01)
        configuration['Monsel']= int((row[0] >> 5) & 0x01)
        configuration['Sign']= int((row[0] >> 4) & 0x01)
        configuration['Zin']= int(((row[0] & 0x0F) << 8) + row[1])

        row = self.read_memory(reg_addr+2)
        configuration['Nfil']= int(row[0])
        configuration['Daa']= int((row[1] >> 7) & 0x01)
        configuration['Hist']= int(row[1] & 0x7F)

        row = self.read_memory(reg_addr+3)
        configuration['Dact']= int((row[0] >> 7) & 0x01)
        configuration['Dac']= int((row[0] >> 5) & 0x03)
        configuration['SSIcfg']= int((row[0] >> 3) & 0x03)
        configuration['Sth']= int(((row[0] & 0x01) << 8)  + ((row[1] >> 6) & 0x03))
        configuration['UVW']= int((row[1] >> 3) & 0x07)
        configuration['Res']= int((row[1] >> 3) & 0x07)

        row = self.read_memory(32)
        configuration['Rpos']= {'valid': int((row[0] >> 7) & 0x01) , 'value':int(((row[0] & 0x0F) << 8) + row[1])}

        row = self.read_memory(33)
        configuration['Apos']= {'valid': int((row[0] >> 7) & 0x01) , 'value':int(((row[0] & 0x0F) << 8) + row[1])}

        row = self.read_memory(34)
        configuration['Weh']= int((row[0] >> 6) & 0x01)
        configuration['Wel']= int((row[0] >> 5) & 0x01)

        row = self.read_memory(35)
        configuration['AGCgain']= int((row[0] >> 4) & 0x0F)
        configuration['Thof']= int((row[0] >> 2) & 0x01)
        configuration['Tho']= int(((row[0] & 0x03) << 8) + row[1])

        if stored :
            self.configuration = configuration
        return configuration

    def set_address(self,addr = 0):
       
        row = self.read_memory(0)
        new_row = [row[0] , (row[1] & 0x80) + addr]
        return self.write_memory( 0 , new_row)

    def get_Absolute_position(self):
        row = self.read_memory(33)
        return int(((row[0] & 0x0F) << 8) + row[1])

    def set_rotation_dir(self):
        pass
    def get_Relative_position(self):
        row = self.read_memory(32)
        return int(((row[0] & 0x0F) << 8) + row[1])
    def check_default_settings(self):
        pass
    def write_default_settings(self):
        pass
    def get_status(self):
        pass
    def scan(self,addr = None):
        pass
    def get_device_list(self):
        pass
    def is_available(self):
        pass
    def read_memory(self, reg):
        return self.bus.read_i2c_block_data(self.address, reg)
        pass
    def write_memory(self, reg , data):
        """
        TODO: Add control on reg and data
        """
        if(self.address is None): raise IOError('No device address defined yet!')

        eeprom = True if (reg < 30) else False
        res = self.bus.write_i2c_block_data(self.address, reg, [((data >> 8) & 0xFF ), (data & 0xFF )])
        if eeprom: sleep(eeprom_write_delay)
        return res

    def check_start_condition(self):
        """ Init repeated start mode"""
        try:
            f = open('/sys/module/i2c_bcm2708/parameters/combined','w+r')
            if(str(f.read(1)).lower() != 'y'):
                f.write('Y')
            f.close()
        except IOError:
            print "Don't have write permission"
    def __str__(self):
        print(self.configuration)
        pass
Exemplo n.º 18
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
Exemplo n.º 19
0
except OSError as e:
    error[3] = e

sleep(delay)

try:
    # write with cmd/idx
    i2c.write_byte_data(addr, cmd, data[0])
except OSError as e:
    error[4] = e

sleep(delay)

try:
    # read block data
    read[2] = i2c.read_i2c_block_data(addr, cmd, cnt)
except OSError as e:
    error[5] = e

sleep(delay)

try:
    # write block data
    i2c.write_i2c_block_data(addr, cmd, data)
except OSError as e:
    error[6] = e

sleep(delay)

try:
    # general call
Exemplo n.º 20
0
class CommunicationI2C(Communication):
    def __init__(self, name="i2c", address="0x00"):
        Communication.__init__(self, name)
        self.bus = None
        self.address = int(address, 16)
        self.timeout = 0.2
        self.stopThread = False
        self.rwMutex = threading.Lock()
        self.startByte = '^'
        self.endByte = '\n'

    def connect(self, address=0x00, timeout=0.2):
        try:
            if address is 0x00:
                address = self.address
            else:
                self.address = address
            self.timeout = timeout
            print "opening i2c ", self.address
            self.bus = SMBus(1)
            self.rwMutex.acquire()
            try:
                self.bus.read_byte(self.address)
                self.connected = True
            except:
                self.connected = False
            self.rwMutex.release()
            print "connected", self.connected
            self.thread = threading.Thread(target=self.__receiveLoop)
            self.thread.start()
            return self.connected
        except:
            # e = sys.exc_info()[0]
            # print e
            return False

    def disconnect(self):
        if self.bus is None:
            return
        self.stopThread = True
        self.thread.join()
        self.connected = False

    def getChecksum(self, message):
        checksum = 0
        for c in message:
            checksum ^= ord(c)
        return checksum

    def sendMessage(self, message):
        while len(self.pendingMessageList):  #empty receive list
            self.pendingMessageList.pop(0)
        if self.bus is None or not self.connected:
            print "send message, not connected"
            return

        if len(message) > 29:
            print "Too long(", len(message), ") ", message
            return

        #print(message)
        checksum = self.getChecksum(message)
        message += chr(checksum)
        #print(message, hex(checksum), chr(checksum))
        message = self.startByte + message + self.endByte

        #print "sending: ", message
        self.rwMutex.acquire()
        #print self.name, "Locked W"
        try:
            #print self.name, "try W"
            self.bus.write_i2c_block_data(self.address, 68, map(ord, message))
            #print self.name, "wrote"
            time.sleep(0.002)
            #print self.name, ">", message
        except:
            print "Write failed on ", self.address
            self.rwMutex.release()
            self.disconnect()
            self.connect(self.address, 1)
            if self.connected:
                print "reconnected ", self.address
        else:
            #print self.name, "About Unlocked W"
            self.rwMutex.release()
            #print self.name, "Unlocked W"

    def __receiveLoop(self):
        errorDetected = False
        while self.bus is not None and self.connected and not self.stopThread:
            time.sleep(0.015)
            message = ""
            self.rwMutex.acquire()
            corruptDetected = False
            try:
                message = self.bus.read_i2c_block_data(self.address, 0, 30)
                time.sleep(0.001)
                message = "".join(map(chr, message))
                payload = message
                #if not message.endswith(self.endByte):
                #    message = ""
                newMessage = ""
                foundStart = False
                foundEnd = False
                for c in message:
                    if not foundStart and c == self.startByte:
                        foundStart = True
                        continue
                    if c == self.endByte and foundStart:
                        foundEnd = True
                        break
                    newMessage += c
                #print("new: {}".format(newMessage))
                checksum = ord(newMessage[-1:])
                newMessage = newMessage[:-1]
                if not foundStart or not foundEnd or self.getChecksum(
                        newMessage) != checksum:
                    corruptDetected = True
                    #print("Start:{} End:{} Checksum:{} Msg:{}".format(foundStart, foundEnd, self.getChecksum(newMessage) == checksum, message))
                message = newMessage
                #message = message.replace(self.endByte(), '')
                message = message.replace(chr(255), '')
                message = message.replace(chr(0), '')
            except Exception as e:
                errorDetected = True
                print e
            self.rwMutex.release()
            if message and len(message) > 0:
                if corruptDetected:
                    #print("{} Corrupt Start:{} End:{} Checksum:{}/{} Msg:{}".format(self.name, foundStart, foundEnd, self.getChecksum(newMessage), checksum, message))
                    #print("corrupt message: {} > {}".format(payload, map(ord, payload)))
                    self.addPendingMessage("ERROR")
                else:
                    #print("valid message: {} > {}".format(payload, map(ord, payload)))
                    self.addPendingMessage(message)
                    print self.name, "<", message

        if errorDetected and not self.stopThread:
            print "recv reconnecting ", self.address
            self.connect(self.address, self.timeout)
Exemplo n.º 21
0
class TCS34725(object):
    address = 0x29

    AGAIN = {0: 1, 1: 4, 2: 16, 3: 60}

    # The middle one should be 0xd6 for the table to be correct...
    # unless, of course, the other two were wrong and 0xD5 is in fact
    # correct.
    # in ms.
    ATIME = {0xff: 2.4, 0xf6: 24, 0xd6: 101, 0xc0: 154, 0x00: 700}

    def __init__(self, bus=1, gain=1, integration_time=2.4):
        self.bus = SMBus(bus)
        self.gain(gain)
        # must be called at least once as readCRGB() relies on its cached value
        self.integration_time(integration_time)
        self.enable()

    def check_ID(self):
        return 0x44 == self._read(0x12)

    def enable(self):
        """see notes on P.15"""
        self._write(0, 0b1)
        sleep(0.003)
        self._write(0, 0b11)

    def disable(self):
        self._write(0, 0)

    def status(self):
        return self._read(0x13)

    def read(self):
        r = self.bus.read_i2c_block_data(self.address, 0x80 + 0x14, 8)
        mc = min((256 - self._it) * 1024, 65535)
        r = {
            'c': float((r[1] << 8) + r[0]) / mc,
            'r': float((r[3] << 8) + r[2]) / mc,
            'g': float((r[5] << 8) + r[4]) / mc,
            'b': float((r[7] << 8) + r[6]) / mc,
        }
        return r

    def integration_time(self, it=None):
        """Integration time it should be one of {2.4,24,101,154,700}ms."""
        if it is not None:
            ii = {self.ATIME[k]: k for k in self.ATIME.keys()}
            if it not in ii:
                raise AttributeError('integration time must be one of {}'.\
                                     format(sorted(ii.keys())))
            self._write(0x01, ii[it])
        tmp = self._read(0x01)
        self._it = tmp
        return self.ATIME[tmp]

    def gain(self, gain=None):
        """gain should be one of {1,4,16,60}."""
        if gain is not None:
            ig = {self.AGAIN[k]: k for k in self.AGAIN.keys()}
            if gain not in ig:
                raise AttributeError('gain must be one of {})'.\
                                     format(sorted(ig.keys())))
            self._write(0x0f, ig[gain])
        return self.AGAIN[self._read(0x0f) & 0b11]

    #def duh(self):
    #    print [self._read(0x00),self._read(0x01),self._read(0x0f)]

    def _read(self, reg):
        # so this would be a so-called "combined protocol"
        return self.bus.read_byte_data(self.address, 0x80 + reg)

    def _write(self, reg, value):
        self.bus.write_byte_data(self.address, 0x80 + reg, value)

    def __del__(self):
        #self.disable()
        pass
Exemplo n.º 22
0
        try:
            if not bme:
                try:
                    bme = BME280(t_mode=BME280_OSAMPLE_8,
                                 p_mode=BME280_OSAMPLE_8,
                                 h_mode=BME280_OSAMPLE_8)
                except:
                    pass
            T = bme.read_temperature()
            H = bme.read_humidity()
        except:
            print('Problem with BME280')

        ###TSL2561
        try:
            data = smbus.read_i2c_block_data(0x39, 0x0C | 0x80, 2)
            data1 = smbus.read_i2c_block_data(0x39, 0x0E | 0x80, 2)
            ch0 = data[1] * 256 + data[0]
            ch1 = data1[1] * 256 + data1[0]
            L = ch0 - ch1
        except:
            print('Problem with TSL2561')

        ###VL53L0X
        start = time.time()
        try:
            D = tof.get_distance()
        except:
            print('Problem with VL53L0X')
        if (time.time() - start) > 2:
            try:
Exemplo n.º 23
0
class I2C(object):
    MASTER = 0
    SLAVE  = 1
    RETRY = 5

    def __init__(self, *args, **kargs):    
        self._bus = 1
        self._smbus = SMBus(self._bus)

    def auto_reset(func):
        def wrapper(*args, **kw):
            try:
                return func(*args, **kw)
            except OSError:
                soft_reset()
                time.sleep(1)
                return func(*args, **kw)
        return wrapper

    @auto_reset
    def _i2c_write_byte(self, addr, data):   
        # self._debug("_i2c_write_byte: [0x{:02X}] [0x{:02X}]".format(addr, data))
        return self._smbus.write_byte(addr, data)
    
    @auto_reset
    def _i2c_write_byte_data(self, addr, reg, data):
        # self._debug("_i2c_write_byte_data: [0x{:02X}] [0x{:02X}] [0x{:02X}]".format(addr, reg, data))
        return self._smbus.write_byte_data(addr, reg, data)
    
    @auto_reset
    def _i2c_write_word_data(self, addr, reg, data):
        # self._debug("_i2c_write_word_data: [0x{:02X}] [0x{:02X}] [0x{:04X}]".format(addr, reg, data))
        return self._smbus.write_word_data(addr, reg, data)
    
    @auto_reset
    def _i2c_write_i2c_block_data(self, addr, reg, data):
        # self._debug("_i2c_write_i2c_block_data: [0x{:02X}] [0x{:02X}] {}".format(addr, reg, data))
        return self._smbus.write_i2c_block_data(addr, reg, data)
    
    @auto_reset
    def _i2c_read_byte(self, addr):  
        # self._debug("_i2c_read_byte: [0x{:02X}]".format(addr))
        return self._smbus.read_byte(addr)

    @auto_reset
    def _i2c_read_i2c_block_data(self, addr, reg, num):
        # self._debug("_i2c_read_i2c_block_data: [0x{:02X}] [0x{:02X}] [{}]".format(addr, reg, num))
        return self._smbus.read_i2c_block_data(addr, reg, num)

    def is_ready(self, addr):
        addresses = self.scan()
        if addr in addresses:
            return True
        else:
            return False

    def scan(self):                            
        cmd = "i2cdetect -y %s" % self._bus
        _, output = self.run_command(cmd)          
        outputs = output.split('\n')[1:]       
       # self._debug("outputs")
        addresses = []
        for tmp_addresses in outputs:
            tmp_addresses = tmp_addresses.split(':')[1]
            tmp_addresses = tmp_addresses.strip().split(' ')    
            for address in tmp_addresses:
                if address != '--':
                    addresses.append(address)
     #   self._debug("Conneceted i2c device: %s"%addresses)                   
        return addresses

    def send(self, send, addr, timeout=0):                     
        if isinstance(send, bytearray):
            data_all = list(send)
        elif isinstance(send, int):
            data_all = []
            d = "{:X}".format(send)
            d = "{}{}".format("0" if len(d)%2 == 1 else "", d)  
            # print(d)
            for i in range(len(d)-2, -1, -2):      
                tmp = int(d[i:i+2], 16)             
                # print(tmp)
                data_all.append(tmp)                
            data_all.reverse()
        elif isinstance(send, list):
            data_all = send
        else:
            raise ValueError("send data must be int, list, or bytearray, not {}".format(type(send)))

        if len(data_all) == 1:                      
            data = data_all[0]
            self._i2c_write_byte(addr, data)
        elif len(data_all) == 2:                    
            reg = data_all[0]
            data = data_all[1]
            self._i2c_write_byte_data(addr, reg, data)
        elif len(data_all) == 3:                    
            reg = data_all[0]
            data = (data_all[2] << 8) + data_all[1]
            self._i2c_write_word_data(addr, reg, data)
        else:
            reg = data_all[0]
            data = list(data_all[1:])
            self._i2c_write_i2c_block_data(addr, reg, data)

    def recv(self, recv, addr=0x00, timeout=0):     
        if isinstance(recv, int):                   
            result = bytearray(recv)
        elif isinstance(recv, bytearray):
            result = recv
        else:
            return False
        for i in range(len(result)):
            result[i] = self._i2c_read_byte(addr)
        return result

    def mem_write(self, data, addr, memaddr, timeout=5000, addr_size=8): #memaddr match to chn
        if isinstance(data, bytearray):
            data_all = list(data)
        elif isinstance(data, int):
            data_all = []
            for i in range(0, 100):
                d = data >> (8*i) & 0xFF
                if d == 0:
                    break
                else:
                    data_all.append(d)
            data_all.reverse()
        self._i2c_write_i2c_block_data(addr, memaddr, data_all)
    
    def mem_read(self, data, addr, memaddr, timeout=5000, addr_size=8):     
        if isinstance(data, int):
            num = data
        elif isinstance(data, bytearray):
            num = len(data)
        else:
            return False
        result = bytearray(num)
        result = self._i2c_read_i2c_block_data(addr, memaddr, num)
        return result

    def test():
        a_list = [0x2d,0x64,0x0]
        b = I2C()
        b.send(a_list,0x14)
Exemplo n.º 24
0
    def task(self):

        avg_voc = 99999

        try:

            # see if an update is ready
            bus = SMBus(I2CBUS)
            resp = bus.read_byte_data(self.I2Caddr, CCS811_REG_STATUS)
            bus.close()

            if resp & CCS811_STATUS_DATA_RDY:
                bus = SMBus(I2CBUS)
                resp = bus.read_i2c_block_data(self.I2Caddr,
                                               CCS811_REG_RESULTS, 4)
                bus.close()
                #e_co2 = (resp[0] << 8) | resp[1]
                t_voc = (resp[2] << 8) | resp[3]

                # make sure reading looks to be within range
                # 1187ppb is max possible
                if t_voc < 1200:
                    self.voc_buff[self.voc_ptr] = t_voc
                    self.voc_ptr += 1
                    if self.voc_ptr >= CCS811_MAX:
                        self.voc_ptr = 0

                    # calculate current average voc value
                    # 3 samples per minute
                    avg_voc = 0
                    for i in range(CCS811_MAX):
                        avg_voc += self.voc_buff[i]
                    avg_voc /= CCS811_MAX_FLOAT
                    avg_voc = int(round(avg_voc))

                    print "ccs811.task() avg voc: %d" % avg_voc

                    f = open(self.FptrVoc, "w")
                    f.write("%d" % avg_voc)
                    f.close()

                    self.newcal = self.get_baseline()
                    if self.newcal != self.oldcal:
                        print "ccs811.task() new baseline: 0x%04x" % self.newcal
                        f = open(self.FptrBase, "w")
                        f.write("0x%04x" % self.newcal)
                        f.close()
                        self.oldcal = self.newcal

                    err = self.error_reg()
                    if err:
                        print "ccs811.task() error reg: 0x%02x" % resp[0]
                        f = open(self.FptrError, "w")
                        f.write("0x%02x" % err)
                        f.close()

                # returning latest value, not average
                return t_voc
            else:
                print "ccs811.task() not ready yet 0x%02x" % resp[0]
                return 99999

        except:
            print "ccs811.tast() error"
            return 99999
Exemplo n.º 25
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.º 26
0
class daq:
    def __init__(self, fs=1666):
        self.__name__ = "daq"
        try:
            self.bus = SMBus(1)
            print("bus connected")
        except Exception as e:
            print("ERROR ", e)

        self.dev = []
        self.fs = fs
        self.dt = 1/self.fs
        self.state = 1
        self.raw = 1
        self.G = 9.81
        self.Rot = np.pi
        
        self.odr = 9  #8=1666Hz 9=3330Hz 10=6660Hz
        self.range = [1, 3]     #[16G, 2000DPS]
        for device in range(128):
            try:
                self.bus.read_byte(device)
                if device == 0x6a:
                    self.dev.append([device, 0x22, 12, '<hhhhhh',['A_'+'Gx','A_'+'Gy','A_'+'Gz','A_'+'Ax','A_'+'Ay','A_'+'Az'], None])
                elif device == 0x6b:
                    self.dev.append([device, 0x22, 12, '<hhhhhh',['B_'+'Gx','B_'+'Gy','B_'+'Gz','B_'+'Ax','B_'+'Ay','B_'+'Az'], None])
                elif device == 0x36:
                    self.dev.append([device, 0x0C, 2, '>H',['rot'], None])
                elif device == 0x48:
                    self.dev.append([device, 0x00, 2, '>h', ['cur'], None])
                self.config(device)
                print("Device Config: ", device)
            except Exception as e:
                #print("ERROR ", e)
                pass
        self.N = len(self.dev)

    def config(self, _device):
        _settings = None
        if _device == 0x6a or _device == 0x6b:
            _settings = [[0x10, (self.odr<<4 | self.range[0]<<2 | 1<<1)],
                         [0x11, (self.odr<<4 | self.range[1]<<2)],
                         [0x12, 0x44],
                         [0x13, 1<<1],
                         [0x15, 0b011],
                         [0X17, (0b000 <<5)]]  #[0x44 is hardcoded acording to LSM6DSO datasheet]
            for _set in _settings:
                try:
                    self.bus.write_byte_data(_device, _set[0], _set[1])
                    
                except Exception as e:
                    print("ERROR: ",e)
        elif _device == 0x48:
            _config = (3<<9 | 0<<8 | 4<<5 | 3)
            _settings = [0x01, [_config>>8 & 0xFF, _config & 0xFF]]
            try:
                self.bus.write_i2c_block_data(_device, _settings[0], _settings[1])
            except Exception as e:
                    print("ERROR: ",e)
        else:
            pass
        

    def pull(self, _device):
       return unpack(_device[3], bytearray(self.bus.read_i2c_block_data(_device[0],_device[1], _device[2])))

    def pulldata(self, _size = 1):
        self.q = queue.Queue()
        gc.collect()
        self.state = 1
        if int(_size) == 0:
                
            t0=tf = time.perf_counter()
            while self.state:
                ti=time.perf_counter()
                if ti-tf>=self.dt:
                    tf = ti                    
                    for _j in range(self.N):
                        try:
                            self.q.put(self.bus.read_i2c_block_data(self.dev[_j][0],self.dev[_j][1],self.dev[_j][2]))
                        except Exception as e:
                            
                            self.q.put((0,)*self.dev[_j][2])
                            print(e)    
                t1 = time.perf_counter()
            print(t1-t0)
        else:
                Ns = int(_size)//self.dt
                i=0
                t0=tf = time.perf_counter()
                while i < Ns:
                    ti=time.perf_counter()
                    if ti-tf>=self.dt:
                        tf = ti
                        i+=1
                        
                        for _j in range(self.N):
                            try:
                                self.q.put(self.bus.read_i2c_block_data(self.dev[_j][0],self.dev[_j][1],self.dev[_j][2]))
                            except Exception as e:
                                self.q.put((0,)*self.dev[_j][2])
                                print(e)
                    t1 = time.perf_counter()
                print(t1-t0)
        return self.q  

    def savedata(self, _q):
        os.chdir(root)
        if 'DATA' not in os.listdir():
            os.mkdir('DATA')
        os.chdir('DATA')
        _path = 'data_{}.csv'.format(len(os.listdir()))
        #os.mkdir(_path)
        #os.chdir(_path)
        
        head=['t']
        #print(head)
        data = self.to_num(_q)
        N = len(data[str(self.dev[0][0])])
        
        data_out = np.linspace(0, N*self.dt, N).reshape((N,1))
        print(data_out.shape)

        for _j in range(self.N):
            arr = np.array(data[str(self.dev[_j][0])])
            head = head+self.dev[_j][-2]
            print(head)
            if str(self.dev[_j][0]) == '54':
                if self.dev[_j][-1] != None:
                    _scale = np.load(root+'/sensors/'+self.dev[_j][-1])
                    data_out = np.hstack((data_out, sp.fix_outlier(arr*_scale)))
                else:
                    data_out = np.hstack((data_out, arr))
            elif str(self.dev[_j][0]) == '106' or str(self.dev[_j][0]) == '107':
                if self.dev[_j][-1] != None:
                    #_param = np.load(root+'/sensors/'+self.dev[_j][-1], allow_pickle=True)
                    params = pd.read_csv(root+'/sensors/'+self.dev[_j][-1], index_col=0)
                    data_out = np.hstack((data_out, np.hstack((self.transl(arr[:,0:3], params['gyr_p'].to_numpy()), self.transl(arr[:,3:6], params['acc_p'].to_numpy())))))
                else:
                    data_out = np.hstack((data_out, arr))
            elif str(self.dev[_j][0]) == '72':
                _scale = np.load(root+'/sensors/'+self.dev[_j][-1])
                data_out = np.hstack((data_out, (arr.astype('int')>>4)*_scale))
            print(data_out)
        
        frame = {}
        for jj in range(len(head)):
            frame[head[jj]]=data_out[:,jj]
        df = pd.DataFrame(frame)
        df.to_csv(_path, index=False)
       
        print('{} saved'.format(_path))
        return data_out

    def to_num(self, _q):
        _data={}
        for _j in range(self.N):
            _data[str(self.dev[_j][0])] = []
        
        while _q.qsize()>0:
            for _j in range(self.N):
                _data[str(self.dev[_j][0])].append(unpack(self.dev[_j][-3], bytearray(_q.get())))
        
        
        return _data
        
    def transl(self, _data, X):
        _T = np.array(X[0:9].reshape((3,3)))
        _b = np.array(X[-3:]).reshape((3,1))
        _data_out = _T@(_data.T-_b)
        
        return _data_out.T

    def calibrate(self, _device):
        os.chdir(root)
        _sensname = input('Connnect sensor and name it: ')
        _sensor = {'name': _sensname}
        self._caldata = []
        print('Iniciando 6 pos calibration')
        NS = int((input('KiloSamples/Position: ') or 6)*1000)

        for _n in range(6):
            input('Position {}'.format(_n+1))
            i=0
            tf = time.perf_counter()
            while i<self.Ns:
                ti=time.perf_counter()
                if ti-tf>=self.dt:
                    tf = ti
                    i+=1
                    self._caldata.append(self.pull(_device))
        ND = int((input('KiloSamples/Rotation: ') or 6)*1000)
        for _n in range(0,6,2):
            input('Rotate 180 deg around axis {}-{}'.format(_n+1,_n+2))
            i=0
            tf = time.perf_counter()
            while i<ND:
                ti=time.perf_counter()
                if ti-tf>=self.dt:
                    tf = ti
                    i+=1
                    self._caldata.append(self.pull(_device))
        
        
        _data = np.array(self._caldata)
        self.acc_raw = _data[0:6*NS,3:6]
        self.gyr_raw = _data[:,0:3]
        np.save('./sensors/'+_sensor['name']+'rawdata.npy', _data)
        print('Calculating calibration parameters. Wait...')
        gc.collect()
        _sensor['acc_p'] = self.calibacc(self.acc_raw, NS)
        gc.collect()
        _sensor['gyr_p'] = self.calibgyr(self.gyr_raw, NS, ND)        
        np.savez('./sensors/'+_sensor['name'], _sensor['gyr_p'], _sensor['acc_p'])
       
        print(_sensor['name']+' saved')
        gc.collect()
        
    
    def calibacc(self, _accdata, NS):        
        #mean values for the 6 positions
        aux=[]
        for ii in range(6):
            aux.append(_accdata[ii*NS:(ii+1)*NS,:].mean(0))
        a_m = np.array(aux).T
        #determination of biases
        aux=[]
        for ii in range(3):
            aux.append((a_m[ii,:].max() + a_m[ii,:].min()) / 2)
        b = np.array(aux, ndmin=2).T

        #unbiased mean values and expected (real) mean values 
        a_mu = a_m-b
        a_mr = np.zeros_like(a_mu)
        for ii in range(3):
            a_mr[ii,a_mu[ii,:].argmax()] = self.G
            a_mr[ii,a_mu[ii,:].argmin()] = -self.G
        #transformation matrix
        T = a_mr@pinv(a_mu)
        
        _param = np.append(T.flatten(), b.T)
       
        return _param
  
    
 
        
    def calibgyr(self, _gyrdata, NS, ND):
        g_s = _gyrdata[0:6*NS,:]            #static gyro data
        g_d = _gyrdata[6*NS:,:]             #dynamic gyro data
        
        b = g_s.mean(0).reshape(3,1)            #bias from mean static measurements
        # integrate dynamic rates to determine total angle
        g_dm = np.zeros((3,3))              

        for ii in range(3):
            g_dm[ii,:] = np.abs(intg.trapz(g_d[ii*ND:(ii+1)*ND,:].T-b,dx=self.dt , axis=1))
        g_dr = np.zeros_like(g_dm)

        for ii in range(3):
            g_dr[ii,g_dm[ii,:].argmax()] = self.Rot
            
        T = g_dr@inv(g_dm)
        
        _param = np.append(T.flatten(), b.T)        
       
        return _param
Exemplo n.º 27
0
#https://www.pololu.com/file/download/LPS25H.pdf?file_id=0J761
from smbus import SMBus
busNum = 1
b = SMBus(busNum)
PTS = 0x5d #Device I2C slave address
PTS_WHOAMI = 0b1011101 #Device self-id

(chip_id, version) = b.read_i2c_block_data(PTS, 0xD0, 2)
print "Chip Id:", chip_id, "Version:", version


if b.read_byte_data(PTS, 0x0f) == PTS_WHOAMI:
    print 'LPS25H detected successfully.'
else:
    print 'No LPS25H detected on bus '+str(busNum)+'.'
Exemplo n.º 28
0
class atm90e26(object):

    def __init__(self):
        self.atm90e26_addrs = {
            'SoftReset'    : { 'addr': 0x00, },
            'SysStatus'    : { 'addr': 0x01, },
            'FuncEn'       : { 'addr': 0x02, },
            'SagTh'        : { 'addr': 0x03, },
            'SmallPMod'    : { 'addr': 0x04, },
            'LastData'     : { 'addr': 0x06, },
            'CalStart'     : { 'addr': 0x20, },
            'PLconstH'     : { 'addr': 0x21, },
            'PLconstL'     : { 'addr': 0x22, },
            'Lgain'        : { 'addr': 0x23, },
            'Lphi'         : { 'addr': 0x24, },
            'Ngain'        : { 'addr': 0x25, },
            'Nphi'         : { 'addr': 0x26, },
            'PStartTh'     : { 'addr': 0x27, },
            'PNolTh'       : { 'addr': 0x28, },
            'QStartTh'     : { 'addr': 0x29, },
            'QNolTh'       : { 'addr': 0x2a, },
            'MMode'        : { 'addr': 0x2b, },
            'CS1'          : { 'addr': 0x2c, },
            'AdjStart'     : { 'addr': 0x30, },
            'Ugain'        : { 'addr': 0x31, },
            'IgainL'       : { 'addr': 0x32, },
            'IgainN'       : { 'addr': 0x33, },
            'Uoffset'      : { 'addr': 0x34, },
            'IoffsetL'     : { 'addr': 0x35, },
            'IoffsetN'     : { 'addr': 0x36, },
            'PoffsetL'     : { 'addr': 0x37, },
            'QoffsetL'     : { 'addr': 0x38, },
            'PoffsetN'     : { 'addr': 0x39, },
            'QoffsetN'     : { 'addr': 0x3a, },
            'CS2'          : { 'addr': 0x3b },

            'APenergy' : { 'addr': 0x40, 'prec': 0.1, 'unit': 'kJ'}, 
            'ANenergy' : { 'addr': 0x41, 'prec': 0.1, 'unit': 'kJ'},
            'ATenergy' : { 'addr': 0x42, 'prec': 0.1, 'unit': 'kJ'},
            'RPenergy' : { 'addr': 0x43, 'prec': 0.1, 'unit': 'kJ'}, 
            'RNenergy' : { 'addr': 0x44, 'prec': 0.1, 'unit': 'kJ'},
            'RTenergy' : { 'addr': 0x45, 'prec': 0.1, 'unit': 'kJ'},
            'EnStatus' : { 'addr': 0x46, },
            'Irms'     : { 'addr': 0x48, 'prec': 0.001, 'unit': 'A'},
            'Urms'     : { 'addr': 0x49, 'prec': 0.01, 'unit': 'V'},
            'Pmean'    : { 'addr': 0x4a, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kW'},
            'Qmean'    : { 'addr': 0x4b, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kVAR'},
            'Freq'     : { 'addr': 0x4c, 'prec': 0.01, 'unit': 'Hz'},
            'PowerF'   : { 'addr': 0x4d, 'sgn': 'msb', 'prec': 0.001, },
            'Pangle'   : { 'addr': 0x4e, 'prec': 0.1, 'sgn': 'msb', 'unit': 'deg'},
            'Smean'    : { 'addr': 0x4f, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kVA'},
            'Irms2'    : { 'addr': 0x68, 'prec': 0.001, 'unit': 'A'},
            'Pmean2'   : { 'addr': 0x6a, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kW'},
            'Qmean2'   : { 'addr': 0x6b, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kVAR'},
            'PowerF2'  : { 'addr': 0x6d, 'sgn': 'msb', 'prec': 0.001, },
            'Pangle2'  : { 'addr': 0x6e, 'prec': 0.1, 'sgn': 'msb', 'unit': 'deg'},
            'SmeanF'   : { 'addr': 0x4f, 'prec': 0.001, 'sgn': 'complement', 'unit': 'kVA'},
        }
        self.atm90e26_reverse_addrs = {}
        for name in self.atm90e26_addrs:
            self.atm90e26_reverse_addrs[self.atm90e26_addrs[name]['addr']] = name

        self.calibvals = {
            'funcen': 0x0,

            'calibration': [
                ('PLconstH', 0x1c),
                ('PLconstL', 0xa90e),
                ('Lgain',    0x0),
                ('Lphi',     0x0),
                ('Ngain',    0x0),
                ('Nphi',     0x0),
                ('PStartTh', 0x8bd),
                ('PNolTh',   0x0),
                ('QStartTh', 0xaec),
                ('QNolTh',   0x0),
                ('MMode',    0x9422 & ~0xe000), # switch to 4x on current sense amp
             ],

            'adjustment': [
                ('Ugain',    14949),
                ('IgainL',   0x8d88),
                ('IgainN',   0x0),
                ('Uoffset',  0x0),
                ('IoffsetL', 0x0),
                ('IoffsetN', 0x0),
                ('PoffsetL', 0x0),
                ('QoffsetL', 0x0),
                ('PoffsetN', 0x0),
                ('QoffsetN', 0x0),
            ],
        }

        self.magic = {
            'reset': 0x789a,
            'cal_mode': 0x5678,
            'check_mode': 0x8765,
            'small_power': 0xa987,
        }

    def loadCalibration(self,cdata):
        for section in self.calibvals:
            if cdata.get(section,None) is not None:
                for varn in cdata[section]:
                    val = cdata[section][varn]
                    if val < 0:
                        val = -val
                        val |= 0x8000
                    if isinstance(val,str):
                        val = int(val,16)
                    idx = 0
                    while idx < len(self.calibvals[section]):
                        if self.calibvals[section][idx][0] == varn:
                            print('Overriding default calibration for ' + varn + ' = ' + str(val))
                            self.calibvals[section][idx] = (varn, val)
                            break
                        idx += 1

    def setup(self, iftype = 'i2c'):
        if iftype == 'i2c':
            from smbus import SMBus
            self.bus = SMBus(1)
            self.addr = 0x32
            self.iftype = iftype
        elif iftype == 'spi':
            import spidev
            self.spi = spidev.SpiDev()
            self.spi.open(0, 0)
            self.spi_speed_hz = 500000 
            self.spi.max_speed_hz = self.spi_speed_hz 
            self.spi.mode = 0x3
            self.spi_bits_per_byte = 8
            self.spi_cs_delay = 10
            self.iftype = iftype
        else:
            self.iftype = None


    def reset(self):

        def writeBunch(self, pairs):
            chk_l = 0
            chk_h = 0
            regnames = []
            plh_wr_stored = None
            for regpair in pairs:
                if False:
                    cs1_afe = self.getReg('CS1')
                    debugprint('CS1: {:04x}'.format(cs1_afe['raw']))

                vn = regpair[0]
                regnames.append(vn)
                wrval = regpair[1]

                # increment the checksum calculation
                wrv_l = wrval & 0xff
                wrv_h = (wrval >> 8) & 0xff
                chk_h ^= wrv_h
                chk_h ^= wrv_l
                chk_l += wrv_h
                chk_l += wrv_l

                self.setReg(vn, wrval)
                time.sleep(0.01)
                res0 = self.getReg(vn)
                time.sleep(0.01)

                # handle PLconstH specially, since it won't show its 
                # new value until PLconstL has been written
                if vn == 'PLconstH':
                    plh_wr_stored = wrval
                else:
                    if not res0 or res0['raw'] != wrval:
                        debugprint('[{}] wrote: {:04x} got {:04x}'.format(vn, wrval,res0['raw']))


                if vn == 'PLconstL':
                    res1 = self.getReg('PLconstH')
                    if not res1 or res1['raw'] != plh_wr_stored:
                        debugprint('[{}] wrote: {:04x} got {:04x}'.format('PLconstH', plh_wr_stored, res1['raw']))



            chk_l &= 0xff
            debugprint('MY chk_h: {:02x} chk_l: {:02x}'.format(chk_h,chk_l))
            return (chk_h << 8) | chk_l


        debugprint('- Resetting atm90e26 chip and setting calibration registers.')

        self.setReg('SoftReset', self.magic['reset'])
        time.sleep(0.5)

        if True:
            self.setReg('CalStart', self.magic['cal_mode'])
            mychk = writeBunch(self, self.calibvals['calibration'])
            self.setReg('CS1',mychk)
            self.setReg('CalStart', self.magic['check_mode'])

        if True:
            self.setReg('AdjStart', self.magic['cal_mode'])
            mychk = writeBunch(self, self.calibvals['adjustment'])
            self.setReg('CS2',mychk)
            self.setReg('AdjStart', self.magic['check_mode'])

        if True:
            cs1_afe = self.getReg('CS1')
            cs2_afe = self.getReg('CS2')
            sys_afe = self.getReg('SysStatus')
            debugprint('CS1: {:04x} CS2: {:04x} SysStatus: {:04x}'.format(cs1_afe['raw'],cs2_afe['raw'],sys_afe['raw']))



    def spi_xfer(self, outd):
        ind = self.spi.xfer2(outd, self.spi_speed_hz, self.spi_cs_delay, self.spi_bits_per_byte)
        return ind

    def _startRead_i2c(self, aname):
        reginfo = self.atm90e26_addrs.get(aname,None)
        if not reginfo:
            return None

        try:
            addr = reginfo['addr']
            self.bus.write_i2c_block_data(self.addr,addr | 0x80,[0,0])
            #time.sleep(0.5)
            return reginfo['addr'] 
        except Exception as e:
            debugprint('- Error writing to i2c device.');
            debugprint(e)
            try:
                debugprint('- attempting to restart i2c')
                self.__init__()
                self.reset()
            except Exception as f:
                pass
        return False


    def setReg(self, aname, data):
        reginfo = self.atm90e26_addrs.get(aname,None)
        if not reginfo:
            return None

        addr = reginfo['addr']
        d1 = (data >> 8) & 0xff
        d0 = data & 0xff
        try:
            if self.iftype == 'i2c':
                self.bus.write_i2c_block_data(self.addr,addr & ~0x80,[d1,d0])
                time.sleep(0.05)
            else:
                self.spi_xfer([addr & ~0x80, d1, d0])
            return True
        except Exception as e:
            debugprint('- Error writing to hardware device: {0}'.format(repr(e)))
            try:
                debugprint('- attempting to restart device')
                self.__init__()
                self.reset()
            except Exception as f:
                pass
        return False

    def _finishRead_i2c(self):
        tries = 10
        while tries:
            try:
                data = self.bus.read_i2c_block_data(self.addr, 1, 4)
                if data[0] == 0x12:
                    addr = data[1] & ~0x80; # address without msb
                    word = (data[2] << 8) | data[3]
                    return { 'addr': addr, 'word': word }
                else:
                    tries -= 1
                    time.sleep(0.01)
            except Exception as e:
                debugprint('Exception reading state: {0}'.format(e))
                tries -= 1;
                time.sleep(0.10)
                try:
                    self.__init__()
                except Exception as f:
                    pass
            #debugprint('_finishRead_i2c tries: {0}'.format(tries))

        return None

    def _polishRead(self, rawres):
        if rawres:
            name = self.atm90e26_reverse_addrs.get(rawres['addr'],'_unknown')
            fmt = self.atm90e26_addrs.get(name,None)
            word = rawres['word']
            val = word + 0
            unit = ''
            if fmt:
                sgn = fmt.get('sgn','unsigned')
                if sgn == 'unsigned':
                    pass
                elif sgn == 'complement':
                    if (word & 0x8000):
                        val -= 65535
                elif sgn == 'msb':
                    if (word & 0x8000):
                        word &= ~0x8000
                        val = -word

                prec = fmt.get('prec',1)
                val *= prec
                unit = fmt.get('unit','')
                return {
                    'addr': rawres['addr'],
                    'aname': name,
                    'raw': word,
                    'value': val,
                    'unit': unit
                }
        return None


    def getReg(self, aname):
        if self.iftype == 'i2c':
            return self.getReg_i2c(aname)
        else:
            return self.getReg_spi(aname)


    def getReg_spi(self, aname):
        reginfo = self.atm90e26_addrs.get(aname,None)
        if not reginfo:
            return None

        addr = reginfo['addr']

        try:
            outd = [ addr | 0x80, 0, 0 ]
            rdata = self.spi_xfer(outd)
            word0 = rdata[1] << 8 | rdata[2]

            outd = [ self.atm90e26_addrs['LastData']['addr'] | 0x80, 0, 0 ]
            rdata = self.spi_xfer(outd)
            word1 = rdata[1] << 8 | rdata[2]

            if word0 == word1:
                res0 = {
                    'addr': addr,
                    'word': word0,
                }
                return self._polishRead(res0)
        except Exception as e:
            debugprint('Exception reading from SPI: {0}'.format(repr(e)))
        return None




    def getReg_i2c(self, aname):
        tries =10
        while tries:
            reqaddr = self._startRead_i2c(aname)
            if reqaddr:
                time.sleep(0.001)
                res0 = self._finishRead_i2c()
                lastaddr = self._startRead_i2c('LastData')
                if lastaddr:
                    time.sleep(0.001)
                    res1 = self._finishRead_i2c()
                    if res1:
                        a0match = res0['addr'] == reqaddr
                        a1match = res1['addr'] == self.atm90e26_addrs['LastData']['addr']
                        vmatch  = res0['word'] == res1['word']
                        if a0match and a1match and vmatch:
                            return self._polishRead(res0)
                        else:
                            if not a0match:
                                debugprint('Request  return addr {:02x} does not match requested {:02x}'.format(res0['addr'],reqaddr))
                            if not a1match:
                                debugprint('LastData return addr {:02x} does not match requested {:02x}'.format(res1['addr'],self.atm90e26_addrs['LastData']['addr']))
                            if not vmatch:
                                debugprint('Read value {:04x} does not match LastData value {:04x}'.format(res0['word'],res1['word']))
            else:
                debugprint("no reqaddr. Maybe {0} isn't right?".format(aname))
            tries -= 1
            debugprint('getReg tries: {0}'.format(tries))
        return None

    def getRegs(self, names):
        res = {}
        for name in names:
            res[name] = self.getReg(name)
        return res
Exemplo n.º 29
0
class TemperaturePressure:

    address = 0x77
    oversampling = 3 # 0..3
    
    def __init__(self):

        # 0 for R-Pi Rev. 1, 1 for Rev. 2
        self.bus = SMBus(1)
        
        # Read whole calibration EEPROM data
        cal = self.bus.read_i2c_block_data(self.address, 0xAA, 22)
        
        # Convert byte data to word values
        self.ac1 = get_short(cal, 0)
        self.ac2 = get_short(cal, 2)
        self.ac3 = get_short(cal, 4)
        self.ac4 = get_ushort(cal, 6)
        self.ac5 = get_ushort(cal, 8)
        self.ac6 = get_ushort(cal, 10)
        self.b1 = get_short(cal, 12)
        self.b2 = get_short(cal, 14)
        self.mb = get_short(cal, 16)
        self.mc = get_short(cal, 18)
        self.md = get_short(cal, 20)
        
        return

    def read(self):
        
        # temperature conversion
        self.bus.write_byte_data(self.address, 0xF4, 0x2E)
        sleep(0.005)
        (msb, lsb) = self.bus.read_i2c_block_data(self.address, 0xF6, 2)
        ut = (msb << 8) + lsb
        
        # pressure conversion
        self.bus.write_byte_data(self.address, 0xF4, 0x34 + (self.oversampling << 6))
        sleep(0.04)
        (msb, lsb, xsb) = self.bus.read_i2c_block_data(self.address, 0xF6, 3)
        up = ((msb << 16) + (lsb << 8) + xsb) >> (8 - self.oversampling)
        
        # calculate temperature
        x1 = ((ut - self.ac6) * self.ac5) >> 15
        x2 = (self.mc << 11) / (x1 + self.md)
        b5 = x1 + x2 
        t = (b5 + 8) >> 4
        
        # calculate pressure
        b6 = b5 - 4000
        b62 = b6 * b6 >> 12
        x1 = (self.b2 * b62) >> 11
        x2 = self.ac2 * b6 >> 11
        x3 = x1 + x2
        b3 = (((self.ac1 * 4 + x3) << self.oversampling) + 2) >> 2
        x1 = self.ac3 * b6 >> 13
        x2 = (self.b1 * b62) >> 16
        x3 = ((x1 + x2) + 2) >> 2
        b4 = (self.ac4 * (x3 + 32768)) >> 15
        b7 = (up - b3) * (50000 >> self.oversampling)
        p = (b7 * 2) / b4
        x1 = (p >> 8) * (p >> 8)
        x1 = (x1 * 3038) >> 16
        x2 = (-7357 * p) >> 16
        p = p + ((x1 + x2 + 3791) >> 4)
        
        return (t/10.0, p / 100)
Exemplo n.º 30
0
addr = 0x77
oversampling = 3        # 0..3

bus = SMBus(2);         # 0 for R-Pi Rev. 1, 1 for Rev. 2
                        # 2 for BeagleBone Green using Grove connector

# return two bytes from data as a signed 16-bit value
def get_short(data, index):
        return c_short((data[index] << 8) + data[index + 1]).value

# return two bytes from data as an unsigned 16-bit value
def get_ushort(data, index):
        return (data[index] << 8) + data[index + 1]

(chip_id, version) = bus.read_i2c_block_data(addr, 0xD0, 2)
print "Chip Id:", chip_id, "Version:", version

print
print "Reading calibration data..."
# Read whole calibration EEPROM data
cal = bus.read_i2c_block_data(addr, 0xAA, 22)

# Convert byte data to word values
ac1 = get_short(cal, 0)
ac2 = get_short(cal, 2)
ac3 = get_short(cal, 4)
ac4 = get_ushort(cal, 6)
ac5 = get_ushort(cal, 8)
ac6 = get_ushort(cal, 10)
b1 = get_short(cal, 12)
Exemplo n.º 31
0

    #leer aceptador de monedas
		before = int(time.time())    #se necesita esto aqui?
		if modo_serial == 'usb':
			bytesToRead = ser_acc.inWaiting()
		elif modo_serial == 'i2c':
			#aca viene lo de Jose Velarde
			bytesToRead = 0
			pass
    #leer rfid
		if modo_serial == 'usb':
			pass
		elif modo_serial == 'i2c':
			try:
				rfid_id = bus.read_i2c_block_data(0x04,0,4)
			except:
				pass


		if bytesToRead > 0:
			formadepago = "cash"
			try:
				os.system('mpg123 -q iguino_sounds/_iguino_beep2.mp3 &')
			except:
				print('no se puedo reproducir audio de moneda')
			now = int(time.time())   #se necesita esto aqui?
			process_id = 1


		if modo_serial == 'i2c':
Exemplo n.º 32
0
irqPin = 17   # IRQ pin for MCP23017

os.system("sudo modprobe uinput")

ui      = UInput({e.EV_KEY: key}, name="retrogame", bustype=e.BUS_USB)
bus     = SMBus(1)
IODIRA  = 0x00
IOCONA  = 0x0A
INTCAPA = 0x10

# 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
Exemplo n.º 33
0
class MCP9804Sensor(object):
    """Represents an MCP9820 i2c sensor connected to a GPIO pin"""
    def __init__(self, connections, logger, params, sensors, actuators):
        """Sets the sensor pin to pud and publishes its current value"""

        self.lastpoll = time.time()

        #Initialise to some time ago (make sure it publishes)
        self.lastPublish = time.time() - 1000

        self.logger = logger
        self.sensorMode = params("Mode")

        # Note the int(xx, 16) here as this is Hex (base 16) in the Config
        self.addr = int(params("Address"), 16)  # 0x1f
        self.bus = SMBus(int(params("Bus")))  # 1

        self.precisionTemp = int(params("PrecisionTemp"))
        self.useF = False

        try:
            if (params("Scale") == 'F'):
                self.useF = True
        except ConfigParser.NoOptionError:
            pass

        #Use 1 reading as default
        self.ARRAY_SIZE = 1

        if (self.sensorMode == "Advanced"):
            #Array size of last readings
            self.ARRAY_SIZE = 5

        #Initialize Array
        self.arrTemperature = [None] * self.ARRAY_SIZE

        self.temperature = None

        self.forcePublishInterval = 60

        self.destination = params("Destination")
        self.poll = float(params("Poll"))

        self.publish = connections

        self.logger.info(
            "----------Configuring MCP9804 Sensor: bus='{0}' address='{1}' poll='{2}' destination='{3}' Initial values: Temp='{4}'"
            .format(self.bus, self.addr, self.poll, self.destination,
                    self.temperature))

        self.publishState()

    def wakeup(self):
        try:
            self.bus.write_word_data(self.addr, 1, 0x0000)
        except:
            self.logger.warn("Wakeup failed..")

    def shutdown(self):
        try:
            self.bus.write_word_data(self.addr, 1, 0x0001)
        except:
            self.logger.warn("Shutdown failed..")

    def convertTemp(self, value):
        return value if self.useF == False else value * 9 / 5.0 + 32

    def checkState(self):
        """Detects and publishes any state change"""

        hasChanged = False
        valueTemp = self.readSensor(True)

        if (valueTemp is None):
            self.logger.warn(
                "Last reading isn't valid. preserving old reading T='{0}'".
                format(self.temperature))
            return

        #Verify reading of temperature
        if (valueTemp != self.temperature):
            self.temperature = valueTemp
            hasChanged = True

        if (hasChanged or
            (time.time() - self.lastPublish) > self.forcePublishInterval):
            self.publishState()

    def publishStateImpl(self, data, destination):
        for conn in self.publish:
            conn.publish(data, destination)

    def publishState(self):
        """Publishes the current state"""
        didPublish = False

        if (self.temperature is not None):
            didPublish = True
            strTemp = str(round(self.temperature, self.precisionTemp))
            self.logger.debug("Publish temperature '{0}' to '{1}'".format(
                strTemp, self.destination + "/temperature"))
            self.publishStateImpl(strTemp, self.destination + "/temperature")

        if (didPublish):
            self.lastPublish = time.time()

    def isReadingValid(self, value, acceptableMin, acceptableMax):
        if (value is None):
            return False

        if ((value >= acceptableMin) and (value <= acceptableMax)):
            return True

        return False

    def readSensor(self, shutdown=True):

        resultTemp = None
        valueTemp = float(-99)
        try:
            if shutdown:
                self.wakeup()
                time.sleep(0.36)

            msb, lsb = self.bus.read_i2c_block_data(self.addr, 5, 2)

            if shutdown:
                self.shutdown()

            tcrit = msb >> 7 & 1
            tupper = msb >> 6 & 1
            tlower = msb >> 5 & 1

            temperature = (msb & 0xf) * 16 + lsb / 16.0

            if msb >> 4 & 1:
                temperature = 256 - temperature

            valueTemp = float(temperature)

        except IOError as ex:
            self.logger.debug("ERROR - {0} - {1}".format(
                ex.errno, ex.strerror))
        finally:
            if shutdown:
                try:
                    self.shutdown()
                except Exception as e:
                    self.logger.debug("ERROR - {0} {1}".format(
                        e.errno, e.strerror))

        #print("Raw reading T:{0}".format(valueTemp ))

        # Is temperature reading valid?
        if (self.isReadingValid(valueTemp, -40.0, 125.0)):
            valueTemp = self.convertTemp(valueTemp)
            self.arrTemperature.append(round(valueTemp, 2))
        else:
            #Reading out of bounds
            return resultTemp

        if (len(self.arrTemperature) > self.ARRAY_SIZE):
            del self.arrTemperature[0]

        if (self.sensorMode == "Advanced"):
            sumTemp = sum(filter(None, self.arrTemperature))
            noTempReadings = len(filter(None, self.arrTemperature))

            if (noTempReadings > 0):
                resultTemp = float(
                    str(round(sumTemp / noTempReadings, self.precisionTemp)))

            #print("readValueAdvanced: Result - Temp:'{0}'".format(resultTemp))
            self.logger.info("readValue: Temp:'{0}'".format(resultTemp))

        #Simple mode -> Just return last reading
        else:
            resultTemp = float(str(round(valueTemp, self.precissionTemp)))

            self.logger.info("readValue: Temp:'{0}'".format(resultTemp))

            #print("readValueSimple: Result - Temp:'{0}'".format(resultTemp))

        return resultTemp
Exemplo n.º 34
0
class MCP3428(object):
    """
	"""
    def __init__(self):
        self.LSB_12BITS = 0.001000
        self.LSB_14BITS = 0.000250
        self.LSB_16BITS = 0.0000625

        self.CW_RDY = 0b10000000
        self.CW_C1 = 0b00000000
        self.CW_C2 = 0b00100000
        self.CW_C3 = 0b01000000
        self.CW_C4 = 0b01100000

        self.CW_CC = 0b00010000
        self.CW_CM = 0b00000000

        self.CW_240SPS = 0b00000000
        self.CW_60SPS = 0b00000100
        self.CW_15SPS = 0b00001000

        self.CW_G1 = 0b00000000
        self.CW_G2 = 0b00000001
        self.CW_G4 = 0b00000010
        self.CW_G8 = 0b00000011

        self.addr = 0
        self.mode = self.CW_CC
        self.sps = self.CW_15SPS
        self.lsb = self.LSB_16BITS
        self.gain = self.CW_G1

    def open(self, bus_num, bus=None):
        if bus != None:
            self.bus = bus
        else:
            self.bus = SMBus()
            self.bus.open(bus_num)

    def addr_is(self, pin0, pin1):
        """
		Calcule l'addresse du chip avec la configuration des pin adresse pin0 et pin1
		None : pin floatante
		True : V+
		False : GND
		"""
        BASE_ADDR = 0b1101000
        if pin0 == None and pin1 == None:
            return BASE_ADDR | 0b000
        if pin0 == False and pin1 == False:
            return BASE_ADDR | 0b000
        if pin0 == False and pin1 == None:
            return BASE_ADDR | 0b001
        if pin0 == False and pin1 == True:
            return BASE_ADDR | 0b010
        if pin0 == None and pin1 == False:
            return BASE_ADDR | 0b011
        if pin0 == True and pin1 == False:
            return BASE_ADDR | 0b100
        if pin0 == True and pin1 == None:
            return BASE_ADDR | 0b101
        if pin0 == True and pin1 == True:
            return BASE_ADDR | 0b110
        if pin0 == None and pin1 == True:
            return BASE_ADDR | 0b111

    def set_addr(self, addr):
        self.addr = addr

    def set_mode(self, mode):
        self.mode = mode & 0b10010011

    def set_channel(self, CW_Cx):
        self.bus.write_byte(
            self.addr, self.CW_RDY | CW_Cx | self.mode | self.sps | self.gain)
        time.sleep(0.12)
        return

    def close(self):
        bus.close()

    def get_value(self):
        buf = self.bus.read_i2c_block_data(self.addr, 0, 2)
        #print buf
        if self.gain == self.CW_G1:
            return (buf[0] << 8 | buf[1]) * self.lsb
        if self.gain == self.CW_G2:
            return (buf[0] << 8 | buf[1]) * self.lsb / 2
        if self.gain == self.CW_G4:
            return (buf[0] << 8 | buf[1]) * self.lsb / 4
        if self.gain == self.CW_G8:
            return (buf[0] << 8 | buf[1]) * self.lsb / 8

    def set_lsb(self, lsb):
        self.lsb = lsb
        if self.lsb == self.LSB_12BITS:
            self.sps = self.CW_240SPS
        if self.lsb == self.LSB_14BITS:
            self.sps = self.CW_60SPS
        if self.lsb == self.LSB_16BITS:
            self.sps = self.CW_15SPS
        return self.sps

    def set_sps(self, sps):
        self.sps = sps
        if self.sps == self.CW_240SPS:
            self.lsb = self.LSB_12BITS
        if self.sps == self.CW_60SPS:
            self.lsb = self.LSB_14BITS
        if self.sps == self.CW_15SPS:
            self.lsb = self.LSB_16BITS
        return self.lsb

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

    def send_general_reset(self):
        self.bus.write_byte(self.addr, 0x06)
        time.sleep(0.5)
        return

    def send_general_latch(self):
        self.bus.write_byte(self.addr, 0x04)
        time.sleep(0.12)
        return

    def send_general_conversion(self):
        self.bus.write_byte(self.addr, 0x08)
        time.sleep(0.12)
        return

    def set_gain(self, gain):
        self.gain = gain
Exemplo n.º 35
0
class MS5611:
    '''
    Driver for reading temperature/pressure MS5611 Pressure Sensor.
    @params bus: can be set as 0 or 1 in rasberry3B+,
                 0 means port SDA.0 while 1 means port SDA.1 in pi
    @params i2c: the address of i2c, i2c is 0x77 when CSB<-->GND, 0x76 when CSB<-->3V3
    @params elevation: height
    '''
    def __init__(self, bus = 1, i2c = 0x77, elevation = 0):
        self.bus = SMBus(bus)
        self.i2c = i2c
        self.elevation = elevation

    def read(self):
        ## Get raw pressure
        self.bus.write_byte(self.i2c, 0x48)
        time.sleep(0.05)

        D1 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D1 = D1[0] * 65536 + D1[1] * 256.0 + D1[2]
        time.sleep(0.05)

        ## Get raw temperature
        self.bus.write_byte(self.i2c, 0x58)
        time.sleep(0.05)
        D2 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D2 = D2[0] * 65536 + D2[1] * 256.0 + D2[2]
        time.sleep(0.05)

        
        ## Read Constants from Sensor
        if hasattr(self, 'C1'):
            C1 = self.C1
        else:
            C1 = self.bus.read_i2c_block_data(self.i2c, 0xA2) #Pressure Sensitivity
            C1 = C1[0] * 256.0 + C1[1]
            self.C1 = C1
            time.sleep(0.05)

        if hasattr(self, 'C2'):
            C2 = self.C2
        else:
            C2 = self.bus.read_i2c_block_data(self.i2c, 0xA4) #Pressure Offset
            C2 = C2[0] * 256.0 + C2[1]
            self.C2 = C2
            time.sleep(0.05)

        if hasattr(self, 'C3'):
            C3 = self.C3
        else:
            C3 = self.bus.read_i2c_block_data(self.i2c, 0xA6) #Temperature coefficient of pressure sensitivity
            C3 = C3[0] * 256.0 + C3[1]
            self.C3 = C3
            time.sleep(0.05)

        if hasattr(self, 'C4'):
            C4 = self.C4
        else:
            C4 = self.bus.read_i2c_block_data(self.i2c, 0xA8) #Temperature coefficient of pressure offset
            C4 = C4[0] * 256.0 + C4[1]
            self.C4 = C4
            time.sleep(0.05)

        if hasattr(self, 'C5'):
            C5 = self.C5
        else:
            C5 = self.bus.read_i2c_block_data(self.i2c, 0xAA) #Reference temperature
            C5 = C5[0] * 256.0 + C5[1]
            self.C5 = C5
            time.sleep(0.05)

        if hasattr(self, 'C6'):
            C6 = self.C6
        else:
            C6 = self.bus.read_i2c_block_data(self.i2c, 0xAC) #Temperature coefficient of the temperature
            C6 = C6[0] * 256.0 + C6[1]
            self.C6 = C6
            time.sleep(0.05)

        
        ## These are the calculations provided in the datasheet for the sensor.
        dT = D2 - C5 * 2**8
        TEMP = 2000 + dT * C6 / 2**23

        ## Set Values to class to be used elsewhere
        self.tempC = TEMP/100.0
        self.tempK = TEMP/100.0 + 273.15

        ## These calculations are all used to produce the final pressure value
        OFF = C2 * 2**16 + (C4 * dT) / 2**7
        SENS = C1 * 2**15 + (C3 * dT) / 2**8
        P = (D1 * SENS / 2**21 - OFF) / 2**15
        self.pressure = P/1000.0

        ## Calculate an offset for the pressure.  This is required so that the readings are correct.
        ##   Equation can be found here: http://en.wikipedia.org/wiki/Barometric_formula
        altOffset = math.exp( (-9.80665 * 0.0289644 * self.elevation) / (8.31432 * self.tempK) )
        self.pressureAdj = ( P/altOffset ) / 1000.0 

    def getTempC(self):
        return self.tempC

    def getPressure(self):
        return self.pressure

    def getPressureAdj(self):
        return self.pressureAdj

    def printResults(self):
        print("Temperature:", round(self.tempC, 2), "C")

        print("Pressure Absolute:", round(self.pressure, 2), "kPa")
        print("         Adjusted:", round(self.pressureAdj, 2), "kPa")
Exemplo n.º 36
0
class MS5611:
    """Driver for reading temperature/pressure MS5611 Pressure Sensor."""
    def __init__(self, bus=1, i2c=0x76, elevation=0):
        """Initialize the Driver.

        Default bus is 1.  If you have a Rev 1 RPi then you will need to use bus 0.
        A bus object can also be passed in if you are sharing it among other modules
        
        Arguments (All optional):
        bus -- 0, 1, or a bus object
        i2c -- I2C address
        elevation -- Elevation in meters"""

        if (bus == 0 or bus == 1):
            self.bus = SMBus(bus)
        else:
            self.bus = bus
        self.i2c = i2c
        self.elevation = elevation

    def setElevation(self, elevation):
        self.elevation = elevation

    def setElevationFt(self, elevation):
        self.elevation = elevation / 3.2808

    def setI2c(self, i2c):
        self.i2c = i2c

    def read(self):
        ## Get raw pressure
        self.bus.write_byte(self.i2c, 0x48)
        time.sleep(0.05)

        D1 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D1 = D1[0] * 65536 + D1[1] * 256.0 + D1[2]
        time.sleep(0.05)

        ## Get raw temperature
        self.bus.write_byte(self.i2c, 0x58)
        time.sleep(0.05)
        D2 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D2 = D2[0] * 65536 + D2[1] * 256.0 + D2[2]
        time.sleep(0.05)

        ## Read Constants from Sensor
        if hasattr(self, 'C1'):
            C1 = self.C1
        else:
            C1 = self.bus.read_i2c_block_data(self.i2c,
                                              0xA2)  #Pressure Sensitivity
            C1 = C1[0] * 256.0 + C1[1]
            self.C1 = C1
            time.sleep(0.05)

        if hasattr(self, 'C2'):
            C2 = self.C2
        else:
            C2 = self.bus.read_i2c_block_data(self.i2c, 0xA4)  #Pressure Offset
            C2 = C2[0] * 256.0 + C2[1]
            self.C2 = C2
            time.sleep(0.05)

        if hasattr(self, 'C3'):
            C3 = self.C3
        else:
            C3 = self.bus.read_i2c_block_data(
                self.i2c,
                0xA6)  #Temperature coefficient of pressure sensitivity
            C3 = C3[0] * 256.0 + C3[1]
            self.C3 = C3
            time.sleep(0.05)

        if hasattr(self, 'C4'):
            C4 = self.C4
        else:
            C4 = self.bus.read_i2c_block_data(
                self.i2c, 0xA8)  #Temperature coefficient of pressure offset
            C4 = C4[0] * 256.0 + C4[1]
            self.C4 = C4
            time.sleep(0.05)

        if hasattr(self, 'C5'):
            C5 = self.C5
        else:
            C5 = self.bus.read_i2c_block_data(self.i2c,
                                              0xAA)  #Reference temperature
            C5 = C5[0] * 256.0 + C5[1]
            self.C5 = C5
            time.sleep(0.05)

        if hasattr(self, 'C6'):
            C6 = self.C6
        else:
            C6 = self.bus.read_i2c_block_data(
                self.i2c, 0xAC)  #Temperature coefficient of the temperature
            C6 = C6[0] * 256.0 + C6[1]
            self.C6 = C6
            time.sleep(0.05)

        ## These are the calculations provided in the datasheet for the sensor.
        dT = D2 - C5 * 2**8
        TEMP = 2000 + dT * C6 / 2**23

        ## Set Values to class to be used elsewhere
        self.tempC = TEMP / 100.0
        self.tempF = TEMP / 100.0 * 9.0 / 5 + 32
        self.tempK = TEMP / 100.0 + 273.15

        ## These calculations are all used to produce the final pressure value
        OFF = C2 * 2**16 + (C4 * dT) / 2**7
        SENS = C1 * 2**15 + (C3 * dT) / 2**8
        P = (D1 * SENS / 2**21 - OFF) / 2**15
        self.pressure = P / 100.0

        ## Calculate an offset for the pressure.  This is required so that the readings are correct.
        ##   Equation can be found here: http://en.wikipedia.org/wiki/Barometric_formula
        altOffset = math.exp(
            (-9.80665 * 0.0289644 * self.elevation) / (8.31432 * self.tempK))
        self.pressureAdj = (P / altOffset) / 100.0

    def getTempC(self):
        return self.tempC

    def getTempF(self):
        return self.tempF

    def getPressure(self):
        return self.pressure

    def getPressureAdj(self):
        return self.pressureAdj

    def getBus(self):
        return self.bus

    def printResults(self):
        print "Temperature:", round(self.tempC, 2), "C"
        print "            ", round(self.tempF, 2), "F"

        print "Pressure Absolute:", round(self.pressure, 2), "hPa"
        print "         Adjusted:", round(self.pressureAdj, 2), "hPa"
        print "         Adjusted:", round(self.convert2In(self.pressureAdj),
                                          2), "in"

    def convert2In(self, pressure):
        return pressure * 0.0295301
Exemplo n.º 37
0
class I2C(_Basic_class):
    MASTER = 0
    SLAVE  = 1
    RETRY = 5

    def __init__(self, *args, **kargs):     # *args表示位置参数(形式参数),可无,; **kargs表示默认值参数,可无。
        super().__init__()
        self._bus = 1
        self._smbus = SMBus(self._bus)

    def _i2c_write_byte(self, addr, data):   # i2C 写系列函数
        self._debug("_i2c_write_byte: [0x{:02X}] [0x{:02X}]".format(addr, data))
        return self._smbus.write_byte(addr, data)
    
    def _i2c_write_byte_data(self, addr, reg, data):
        self._debug("_i2c_write_byte_data: [0x{:02X}] [0x{:02X}] [0x{:02X}]".format(addr, reg, data))
        return self._smbus.write_byte_data(addr, reg, data)
    
    def _i2c_write_word_data(self, addr, reg, data):
        self._debug("_i2c_write_word_data: [0x{:02X}] [0x{:02X}] [0x{:04X}]".format(addr, reg, data))
        return self._smbus.write_word_data(addr, reg, data)
    
    def _i2c_write_i2c_block_data(self, addr, reg, data):
        self._debug("_i2c_write_i2c_block_data: [0x{:02X}] [0x{:02X}] {}".format(addr, reg, data))
        return self._smbus.write_i2c_block_data(addr, reg, data)
    
    def _i2c_read_byte(self, addr):   # i2C 读系列函数
        self._debug("_i2c_read_byte: [0x{:02X}]".format(addr))
        return self._smbus.read_byte(addr)

    def _i2c_read_i2c_block_data(self, addr, reg, num):
        self._debug("_i2c_read_i2c_block_data: [0x{:02X}] [0x{:02X}] [{}]".format(addr, reg, num))
        return self._smbus.read_i2c_block_data(addr, reg, num)

    def is_ready(self, addr):
        addresses = self.scan()
        if addr in addresses:
            return True
        else:
            return False

    def scan(self):                             # 查看有哪些i2c设备
        cmd = "i2cdetect -y %s" % self._bus
        _, output = self.run_command(cmd)          # 调用basic中的方法,在linux中运行cmd指令,并返回运行后的内容
        
        outputs = output.split('\n')[1:]        # 以回车符为分隔符,分割第二行之后的所有行
        self._debug("outputs")
        addresses = []
        for tmp_addresses in outputs:
            if tmp_addresses == "":
                continue
            tmp_addresses = tmp_addresses.split(':')[1]
            tmp_addresses = tmp_addresses.strip().split(' ')    # strip函数是删除字符串两端的字符,split函数是分隔符
            for address in tmp_addresses:
                if address != '--':
                    addresses.append(int(address, 16))
        self._debug("Conneceted i2c device: %s"%addresses)                   # append以列表的方式添加address到addresses中
        return addresses

    def send(self, send, addr, timeout=0):                      # 发送数据,addr为从机地址,send为数据
        if isinstance(send, bytearray):
            data_all = list(send)
        elif isinstance(send, int):
            data_all = []
            d = "{:X}".format(send)
            d = "{}{}".format("0" if len(d)%2 == 1 else "", d)  # format是将()中的内容对应填入{}中,()中的第一个参数是一个三目运算符,if条件成立则为“0”,不成立则为“”(空的意思),第二个参数是d,此行代码意思为,当字符串为奇数位时,在字符串最强面添加‘0’,否则,不添加, 方便以下函数的应用
            # print(d)
            for i in range(len(d)-2, -1, -2):       # 从字符串最后开始取,每次取2位
                tmp = int(d[i:i+2], 16)             # 将两位字符转化为16进制
                # print(tmp)
                data_all.append(tmp)                # 添加到data_all数组中
            data_all.reverse()
        elif isinstance(send, list):
            data_all = send
        else:
            raise ValueError("send data must be int, list, or bytearray, not {}".format(type(send)))

        if len(data_all) == 1:                      # 如果data_all只有一组数
            data = data_all[0]
            self._i2c_write_byte(addr, data)
        elif len(data_all) == 2:                    # 如果data_all只有两组数
            reg = data_all[0]
            data = data_all[1]
            self._i2c_write_byte_data(addr, reg, data)
        elif len(data_all) == 3:                    # 如果data_all只有三组数
            reg = data_all[0]
            data = (data_all[2] << 8) + data_all[1]
            self._i2c_write_word_data(addr, reg, data)
        else:
            reg = data_all[0]
            data = list(data_all[1:])
            self._i2c_write_i2c_block_data(addr, reg, data)

    def recv(self, recv, addr=0x00, timeout=0):     # 接收数据
        if isinstance(recv, int):                   # 将recv转化为二进制数
            result = bytearray(recv)
        elif isinstance(recv, bytearray):
            result = recv
        else:
            return False
        for i in range(len(result)):
            result[i] = self._i2c_read_byte(addr)
        return result

    def mem_write(self, data, addr, memaddr, timeout=5000, addr_size=8): #memaddr match to chn
        if isinstance(data, bytearray):
            data_all = list(data)
        elif isinstance(data, list):
            data_all = data
        elif isinstance(data, int):
            data_all = []
            data = "%x"%data
            if len(data) % 2 == 1:
                data = "0" + data
            # print(data)
            for i in range(0, len(data), 2):
                # print(data[i:i+2])
                data_all.append(int(data[i:i+2], 16))
        else:
            raise ValueError("memery write require arguement of bytearray, list, int less than 0xFF")
        # print(data_all)
        self._i2c_write_i2c_block_data(addr, memaddr, data_all)
    
    def mem_read(self, data, addr, memaddr, timeout=5000, addr_size=8):     # 读取数据
        if isinstance(data, int):
            num = data
        elif isinstance(data, bytearray):
            num = len(data)
        else:
            return False
        result = bytearray(self._i2c_read_i2c_block_data(addr, memaddr, num))
        return result
    
    def readfrom_mem_into(self, addr, memaddr, buf):
        buf = self.mem_read(len(buf), addr, memaddr)
        return buf
    
    def writeto_mem(self, addr, memaddr, data):
        self.mem_write(data, addr, memaddr)

# i2c = I2C()
# i2c.scan()
# i2c.mem_write(0xff53773, 20, 20)
Exemplo n.º 38
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.º 39
0
    def __init__(self, name, i2c_addr):
        self.I2Caddr = i2c_addr

        directory = "/tmp/" + name
        if not os.path.exists(directory):
            os.makedirs(directory)

        self.FptrVoc = directory + "/voc"
        self.FptrBase = directory + "/base"
        self.FptrError = directory + "/error"

        # to retreave RH values for compensation
        self.FptrTemp = "/tmp/HTU21D/tc"
        self.FptrHumid = "/tmp/HTU21D/rh"

        # for maintaining the moving averages
        self.voc_buff = [0] * CCS811_MAX
        self.voc_ptr = 0

        # for tracking baseline value changes
        self.newcal = 0
        self.oldcal = 0
        # to track RH compenation event
        self.comp_minute = CCS811_T_MAX
        # Long term T & RH averaging
        self.temp_buff = [23] * CCS811_T_MAX
        self.rh_buff = [50] * CCS811_T_MAX

        bus = SMBus(I2CBUS)
        resp = bus.read_byte_data(self.I2Caddr, CCS811_REG_STATUS)
        print "ccs811.init() status reg: 0x%02x" % resp
        if resp & CCS811_APP_VALID:
            bus.write_byte(self.I2Caddr, CCS811_APP_START)
            print "ccs811.init() starting application"
        else:
            print "ccs811.init() failed to start application"
            bus.close()
            sys.exit(10)

        time.sleep(1)

        # Start making measurements
        bus.write_byte_data(self.I2Caddr, CCS811_REG_MEAS_MODE,
                            CCS811_MEAS_MODE_ON)
        resp = bus.read_byte_data(self.I2Caddr, CCS811_REG_ERROR)
        if resp:
            print "ccs811.init() error reg: 0x%02x" % resp
            sys.exit(11)

        # Display CCS811 information on startup
        resp = bus.read_byte_data(self.I2Caddr, CCS811_HW_ID)
        print "ccs811.inint() HW ID: 0x%02x" % resp
        resp = bus.read_byte_data(self.I2Caddr, CCS811_VER_HW)
        print "ccs811.inint() HW Ver: 0x%02x" % resp
        resp = bus.read_i2c_block_data(self.I2Caddr, CCS811_VER_APP, 2)
        major = resp[0] & 0xf0 >> 4
        minor = resp[0] & 0x0f
        trivial = resp[1]
        print "css811.init() app ver: %d.%d.%d" % (major, minor, trivial)

        resp = bus.read_byte_data(self.I2Caddr, CCS811_REG_ERROR)
        if resp:
            print "ccs811.init() error reg: 0x%02x" % resp
            sys.exit(12)

        # Init envronmental compensation registers
        temp_c = 23
        r_humidity = 50
        self.set_comp(temp_c, r_humidity)
        # will implement periodically in loop
        #print "CCS811 init complete"
        bus.close()
Exemplo n.º 40
0
class nunchuck:
  
  def __init__(self):
    if rpi.RPI_REVISION == 1:
      i2c_bus = 0
    elif rpi.RPI_REVISION == 2:
      i2c_bus = 1
    else:
      print "Unable to determine Raspberry Pi revision."
      exit
    self.bus = SMBus(i2c_bus)
    self.bus.write_byte_data(0x52, 0xF0, 0x55)
    
  def read(self):
    buf = self.bus.read_i2c_block_data(0x52, 0x00, 6)
    data = [0x00]*6

    for i in range(len(buf)):
      data[i] = buf[i]
    return data

  def raw(self):
    data = self.read()
    return data

  def joystick(self):
    data = self.read()
    return data[0],data[1]

  def accelerometer(self):
    data = self.read()
    return data[2],data[3],data[4]

  def button_c(self):
    data = self.read()
    butc = (data[5] & 0x02)
    if butc == 0:
      return True
    else:
      return False

  def button_z(self):
    data = self.read()
    butc = (data[5] & 0x01)
    if butc == 0:
      return True
    else:
      return False    


  def joystick_x(self):
    data = self.read()
    return data[0]

  def joystick_y(self):
    data = self.read()
    return data[1]

  def accelerometer_x(self):
    data = self.read()
    return data[2]

  def accelerometer_y(self):
    data = self.read()
    return data[3]
  
  def accelerometer_z(self):
    data = self.read()
    return data[4]

  
  def scale(self,value,_min,_max,_omin,_omax):
    return (value - _min) * (_omax - _omin) // (_max - _min) + _omin
Exemplo n.º 41
0
class WeatherStation:
  def __init__(self, dataFile='/dev/null'):
    self.dataFile = dataFile
    self.fetched = False

    # Initialise the BMP085 and use STANDARD mode (default value)
    # self.bmp = BMP085(0x77, debug=True)
    self.bmp = BMP085(0x77)
    
    # To specify a different operating mode, uncomment one of the following:
    # self.bmp = BMP085(0x77, 0)  # ULTRALOWPOWER Mode
    # self.bmp = BMP085(0x77, 1)  # STANDARD Mode
    # self.bmp = BMP085(0x77, 2)  # HIRES Mode
    # self.bmp = BMP085(0x77, 3)  # ULTRAHIRES Mode

    # Initilize HIH-6130.
    bus = GFDITools.guessBus()
    self.HIH6130 = SMBus(bus=bus)

    # Temporary storage array for HIH6130 data
    self.blockData = [0, 0, 0, 0]


  def fetchData(self):
    # Fetch temp & pressure data from BMP
    self.temp = self.bmp.readTemperature()
    self.pressure = self.bmp.readPressure() / 100.0
    # Altitude seems buggy, so we're skipping it for now.
    # altitude = self.bmp.readAltitude()

    # Tell HIH-6130 we want temperature and humidity data.
    self.HIH6130.write_quick(0x27)
    # Wait for it.
    time.sleep(0.050)
    # Read the data we requested.
    blockData = self.HIH6130.read_i2c_block_data(0x27, 0)
    # Process the data.
    self.status = (blockData[0] & 0xc0) >> 6
    self.humidity = (((blockData[0] & 0x3f) << 8) + blockData[1]) * 100.0 / 16383.0
    self.tempC = ((blockData[2] << 6) + ((blockData[3] & 0xfc) >> 2)) * 165.0 / 16383.0 - 40.0
    # tempF = tempC*9.0/5.0 + 32.0

    # Make a note that there is now data to be had.
    self.fetched = True


  def printData(self):
    # print data to screen
    # print "Data:       ", "%02x "*len(d)%tuple(d)
    # print "Status:     ", status
    if self.fetched:
      print "Humidity:   %.2f" % self.humidity, "%RH"
      print "Temperature:    %.2f C" % self.tempC
      print "Barometric Pressure:    %.2f hPa" % self.pressure
      print "Temperature:    %.2f C" % self.temp
    else:
      print "No data has been fetched."
      return -1


  def recordData(self):
    if self.fetched:
      if not os.path.exists(self.dataFile):
        with open(self.dataFile, 'w') as csvfile:
          datawriter = csv.writer(
            csvfile,
            quotechar=',',
            quoting=csv.QUOTE_MINIMAL
          )
          datawriter.writerow([
            'Date',
            'Temp(C)',
            'Pressure(hPa)',
            'Humidity(%RH)'
          ])

      with open(self.dataFile, 'a+') as csvfile:
        datawriter = csv.writer(csvfile, quotechar=',', quoting=csv.QUOTE_MINIMAL)
        datawriter.writerow([datetime.datetime.now(), self.tempC, self.pressure, self.humidity])
    else:
      print "No data has been fetched."
      return -1
Exemplo n.º 42
0
class Device(object):
    """Class for communicating with an I2C device using the adafruit-pureio pure
    python smbus library, or other smbus compatible I2C interface. Allows reading
    and writing 8-bit, 16-bit, and byte array values to registers
    on the device."""
    def __init__(self, address, busnum, i2c_interface=None):
        """Create an instance of the I2C device at the specified address on the
        specified I2C bus number."""
        self._address = address
        if i2c_interface is None:
            # Use pure python I2C interface if none is specified.
            # import Adafruit_PureIO.smbus
            self._bus = SMBus(busnum)
        else:
            # Otherwise use the provided class to create an smbus interface.
            self._bus = i2c_interface(busnum)
        self._logger = logging.getLogger('Adafruit_I2C.Device.Bus.{0}.Address.{1:#0X}' \
                                .format(busnum, address))

    def writeRaw8(self, value):
        """Write an 8-bit value on the bus (without register)."""
        value = value & 0xFF
        self._bus.write_byte(self._address, value)
        self._logger.debug("Wrote 0x%02X",
                     value)

    def write8(self, register, value):
        """Write an 8-bit value to the specified register."""
        value = value & 0xFF
        self._bus.write_byte_data(self._address, register, value)
        self._logger.debug("Wrote 0x%02X to register 0x%02X",
                     value, register)

    def write16(self, register, value):
        """Write a 16-bit value to the specified register."""
        value = value & 0xFFFF
        self._bus.write_word_data(self._address, register, value)
        self._logger.debug("Wrote 0x%04X to register pair 0x%02X, 0x%02X",
                     value, register, register+1)

    def writeList(self, register, data):
        """Write bytes to the specified register."""
        self._bus.write_i2c_block_data(self._address, register, data)
        self._logger.debug("Wrote to register 0x%02X: %s",
                     register, data)

    def readList(self, register, length):
        """Read a length number of bytes from the specified register.  Results
        will be returned as a bytearray."""
        results = self._bus.read_i2c_block_data(self._address, register, length)
        self._logger.debug("Read the following from register 0x%02X: %s",
                     register, results)
        return results

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

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

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

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

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

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

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

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

    def readS16BE(self, register):
        """Read a signed 16-bit value from the specified register, in big
        endian byte order."""
        return self.readS16(register, little_endian=False)
Exemplo n.º 43
0
deg = u'\N{DEGREE SIGN}'

# sqlite config
# CREATE TABLE temp_humidity(id INTEGER primary key, datetime DATETIME DEFAULT CURRENT_TIMESTAMP, temp_c REAL NOT NULL, temp_f REAL NOT NULL, humidity INTEGER NOT NULL);
sqliteCon = sqlite.connect(dbPath)


# Main loop
while True:
    # Get the current system date and time
    datetime = time.strftime('%m/%d/%Y %H:%M:%S')

    # Read data from sensor
    bus.write_byte(ADDR, 0x00)
    ans = bus.read_i2c_block_data(ADDR, 0x00, 4)

    # Convert to human readable humdidity
    humidity = ((ans[0] & 0x3f) << 8) + ans[1]
    humidity = humidity * float('6.10e-3')
    humidity = '{:.0f}'.format(humidity)

    # Convert to human readable temperature
    tempC = (ans[2] << 8) + ans[3]
    tempC = tempC >> 2
    tempC = (tempC * float('1.007e-2')) - 40
    tempF = (tempC * 1.8) + 32

    #insert into SQLITE database
    cursor = sqliteCon.cursor()
    cursor.execute("INSERT INTO temp_humidity (datetime, temp_c, temp_f, humidity) VALUES (?, ?, ?, ?)", (time.strftime('%Y-%m-%dT%H:%M:%S'), tempC, tempF, humidity))
Exemplo n.º 44
0
class DS3231:
    """Class to read/write time from/to DS3231"""

	## Control constants
    _SLAVE_ADDR         = 0x68
    _TIME_START_ADDR    = 0x00
    _TEMP_START_ADDR    = 0x11

    _REG_SECONDS        = 0x00
    _REG_MINUTES        = 0x01
    _REG_HOURS          = 0x02
    _REG_DAY            = 0x03
    _REG_DATE           = 0x04
    _REG_MONTH          = 0x05
    _REG_YEAR           = 0x06
    _REG_CONTROL        = 0x07


    def __init__(self, device_number = 1):
        """Opens the i2c device (assuming that the kernel modules have been
        loaded) & run soft reset. (user register leaved to default value)"""
        try:
            self.bus = SMBus(device_number)
        except i2cError:
            #raise i2cError
            pass

        if DEBUG:
            print("DS3231 init done.")

    def getTime(self):
        """ """
        try:
            data = self.bus.read_i2c_block_data(self._SLAVE_ADDR,0x00,7)
        except i2cError:
			#raise i2cError
            pass
        sec     = self._bcd_to_int(data[0] & 0x7F)
        min     = self._bcd_to_int(data[1] & 0x3F)
        hour    = self._bcd_to_int(data[2])
        day     = self._bcd_to_int(data[3])
        date    = self._bcd_to_int(data[4])
        month   = self._bcd_to_int(data[5])
        year    = self._bcd_to_int(data[6])
        if DEBUG:
            print(datetime((21-1)*100 + year, month,date,hour,min,sec,0,tzinfo
                = None))
            #print(*data, sep='\t')
        return datetime((21-1)*100 + year, \
                month,date,hour,min,sec,0,tzinfo=None)
    def setTime(self,timetuple):
        """
			write Time/date Information to Ds3231
			Range: seconds [0,59], minutes [0,59], hours [0,23],
					day [0,7], date [1-31], month [1-12], year [0-99].
        """
        if  self.checkTimeDataValidity(timetuple)is True:
            #write seconds
            regSec  = self._int_to_bcd(timetuple[5])
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_SECONDS,regSec)
            #write minutes
            regMin  = self._int_to_bcd(timetuple[4])
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_MINUTES,regMin)
            #write hours
            regHr = self._int_to_bcd(timetuple[3])
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_HOURS,regHr)
            #write Date
            regDate = self._int_to_bcd(timetuple[2])
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_DATE,regDate)
            #write month
            regMonth = self._int_to_bcd(timetuple[1])
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_MONTH,regMonth)
            #write year
            regYr = self._int_to_bcd(timetuple[0]-2000)
            self.bus.write_byte_data(self._SLAVE_ADDR,self._REG_YEAR,regYr)

    def setTimeNow(self):
        """
            Set time to datetime.now(). Return tuple needed by setTime()
        """
        #TODO:  Get a better function to check  if the pi is online
        if self.checkIfOnline() is not None:
            tmp = datetime.now()
            self.setTime((tmp.year,tmp.month, tmp.day,tmp.hour,tmp.minute,tmp.second ))
        else:
            raise ConnectionError("Please connect your Pi to the internet first...")

    @staticmethod
    def checkIfOnline():
        """ Check if the pi is online """
        try:
            import requests
        except ImportError:
            print('Please make sure Python library requests is installed')
        r = requests.get('https://api.github.com/events')
        if r is True:
            return True
        else:
            return False
    @staticmethod
    def checkTimeDataValidity(timetuple):
        """
            Checks time data inputs
        """
        if 2000 <= timetuple[0] <= 2099 and  \
           1 <= timetuple[1] <= 12 and  \
           1 <= timetuple[2] <= 31 and \
           0 <= timetuple[3] <= 23 and  \
           0 <= timetuple[4] <= 59 and  \
           0 <= timetuple[5] <= 59:
            return True
        else:
            return False


    @staticmethod
    def _bcd_to_int(bcd):
        """
            Decode a 2x4bit BCD to a integer.
        """
        out = 0
        for d in (bcd >> 4, bcd):
            for p in (1, 2, 4 ,8):
                if d & 1:
                    out += p
                d >>= 1
            out *= 10
        return int(out / 10)

    @staticmethod
    def _int_to_bcd(n):
        """
            Encode a one or two digits number to the BCD.
        """
        bcd = 0
        for i in (n // 10, n % 10):
            for p in (8, 4, 2, 1):
                if i >= p:
                    bcd += 1
                    i -= p
                bcd <<= 1
        return bcd >> 1
Exemplo n.º 45
0
class UltrasonicCapteur:

    _PORTS = "34"  # Liste des ports disponibles

    def __init__(self, port):
        if port not in UltrasonicCapteur._PORTS:
            raise CapteurPortErreur
        self._port = port
        if port == "3":
            self._read_addr = 2
            self._write_addr = 3
        else:
            self._read_addr = 2
            self._write_addr = 3
        self._bus = SMBus(1)

    def getPort(self):
        return self._port

    def setPort(self, port):
        if port not in TouchCapteur._PORTS:
            raise CapteurPortErreur
        self._port = port

    def getInfos(self):
        pass

    def setScaleFactor(self, value):
        self._bus.write_byte_data(self._write_addr, 0x51, value)
        time.sleep(0.1)

    def setScaleDivisor(self, value):
        self._bus.write_byte_data(self._write_addr, 0x52, value)
        time.sleep(0.1)

    def setActualZero(self, value):
        self._bus.write_byte_data(self._write_addr, 0x50, value)
        time.sleep(0.1)

    def setInterval(self, value):
        self._bus.write_byte_data(self._write_addr, 0x40, value)
        time.sleep(0.1)

    def getInterval(self):
        data = self._bus.read_i2c_block_data(self._read_addr, 0x40, 1)
        time.sleep(0.1)
        return data[0]

    def getDistance(self):
        # Retourne la distance devant le capteur.
        # self._bus.write_byte_data(self._write_addr, 0x41, 0x01)
        time.sleep(0.1)
        data = self._bus.read_i2c_block_data(self._read_addr, 0x42, 8)
        distance = (data[0] + data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7]) / 8
        return distance

    def __repr__(self):
        # Quand on entre notre objet dans l'interpréteur
        return "Capteur sur le port {}\nVersion : V1.0\nID produit : LEGO\nDistance : {}\t".format(
            self._port, self.getDistance()
        )
Exemplo n.º 46
0
# read Atmel AT30TSE004A temp through I2C

from smbus import SMBus
i2c = SMBus(0)
atmelraw = i2c.read_i2c_block_data(0x1e,0x05,2)
atmeltemp = 16.0*(atmelraw[0] & 0xf) + (atmelraw[1] & 0xfe)/16.0
print "Atmel temp: ", atmeltemp

# read Zynq XADC temp through IIO driver (XAPP1172, UG480)

f = open('/sys/bus/iio/devices/iio:device0/in_temp0_raw','r')
zynqraw = f.read()
f.close()
zynqtemp = int(zynqraw)*503.975/4096 - 273.15
print "Zynq temp: ", zynqtemp



Exemplo n.º 47
0
class I2C(object):
    """ Class to set up and access I2C devices.
    """

    ##
    ## Class methods
    ##

    ## Private methods
    def __init__(self, busId = 1):
        """ Initialize the I2C bus. """
        self._i2c = SMBus(busId)


    def __del__(self):
        """ Clean up routines. """
        try:
            # Remove SMBus connection
            del(self._i2c)
        except:
            pass


    def _combineLoHi(self, loByte, hiByte):
        """ Combine low and high bytes to an unsigned 16 bit value. """
        return (loByte | hiByte << 8)


    def _combineSignedLoHi(self, loByte, hiByte):
        """ Combine low and high bytes to a signed 16 bit value. """
        combined = self._combineLoHi (loByte, hiByte)
        return combined if combined < 32768 else (combined - 65536)


    def _combineXLoLoHi(self, xloByte, loByte, hiByte):
        """ Combine extra low, low, and high bytes to an unsigned 24 bit
            value.
        """
        return (xloByte | loByte << 8 | hiByte << 16)


    def _combineSignedXLoLoHi(self, xloByte, loByte, hiByte):
        """ Combine extra low, low, and high bytes to a signed 24 bit
            value.
        """
        combined = self._combineXLoLoHi(xloByte, loByte, hiByte)
        return combined if combined < 8388608 else (combined - 16777216)


    def _getSensorRawLoHi1(self, address, outRegs):
        """ Return a scalar representing the combined raw signed 16 bit
            value of the output registers of a one-dimensional sensor,
            e.g. temperature.
            'address' is the I2C slave address.
            'outRegs' is a list of the output registers to read.
        """
        # Read register outputs and combine low and high byte values
        xl = self._readRegister(address, outRegs[0])
        xh = self._readRegister(address, outRegs[1])

        xVal = self._combineSignedLoHi(xl, xh)
        # Return the scalar
        return xVal


    def _getSensorRawXLoLoHi1(self, address, outRegs):
        """ Return a scalar representing the combined raw signed 24 bit
            value of the output registers of a one-dimensional sensor,
            e.g. temperature.
            'address' is the I2C slave address.
            'outRegs' is a list of the output registers to read.
        """
        # Read register outputs and combine low and high byte values
        xxl = self._readRegister(address, outRegs[0])
        xl = self._readRegister(address, outRegs[1])
        xh = self._readRegister(address, outRegs[2])

        xVal = self._combineSignedXLoLoHi(xxl, xl, xh)
        # Return the scalar
        return xVal


    def _getSensorRawLoHi3(self, address, outRegs):
        """ Return a vector (i.e. list) representing the combined
            raw signed 16 bit values of the output registers of a
            3-dimensional (IMU) sensor.
            'address' is the I2C slave address.
            'outRegs' is a list of the output registers to read.
        """
        # Read register outputs and combine low and high byte values
        xl = self._readRegister(address, outRegs[0])
        xh = self._readRegister(address, outRegs[1])
        yl = self._readRegister(address, outRegs[2])
        yh = self._readRegister(address, outRegs[3])
        zl = self._readRegister(address, outRegs[4])
        zh = self._readRegister(address, outRegs[5])

        xVal = self._combineSignedLoHi(xl, xh)
        yVal = self._combineSignedLoHi(yl, yh)
        zVal = self._combineSignedLoHi(zl, zh)

        # Return the vector
        return [xVal, yVal, zVal]


    def _readRegister(self, address, register):
        """ Read a single I2C register. """
        return self._i2c.read_byte_data(address, register)


    def _readRegisters(self, address, register, count):
        """ Read (up to 32) 'count' consecutive I2C registers. """
        return self._i2c.read_i2c_block_data(address, register, count)


    def _read(self, address):
        """ Read a single byte from the I2C device without specifying a
            register.
        """
        return self._i2c.read_byte(address)


    def _writeRegister(self, address, register, value):
        """ Write a single byte to a I2C register. Return the value the
            register had before the write.
        """
        valueOld = self._readRegister(address, register)
        self._i2c.write_byte_data(address, register, value)
        return valueOld


    def _write(self, address, value):
        """ Write a single byte to the I2C device without specifying a
            register.
        """
        return self._i2c.write_byte(address, value)


    def _testRegister(self, address, register):
        """ Check, if a I2C register is readable/accessible. """
        try:
            return self._readRegister(address, register)
        except:
            return -1
Exemplo n.º 48
0
class BMP280:
    def __init__(self, address=BMP280_DEFAULT_ADRESS):
        self.i2c = SMBus()
        self.i2c.open(1)
        self.address = address
        self._load_calibration()
        self.i2c.write_byte_data(self.address, BMP280_CONTROL, 0x3F)

    def i2c_check(self):
        """Output should be 88, if not. I2c not correct"""
        data = self.i2c.read_byte_data(self.address, 0xD0)
        print(data)

    def _readU16(self, reg):
        """Reads an unsigned 16 bit value van i2c"""
        result = self.i2c.read_word_data(self.address, reg)
        return result

    def _readS16(self, reg):
        """Reads a signed 16 bit value van i2c"""
        result = self._readU16(reg)
        if result > 32767:
            result -= 65536
        return result

    def _load_calibration(self):
        self.cal_t1 = int(self._readU16(BMP280_DIG_T1))  # UINT16
        self.cal_t2 = int(self._readS16(BMP280_DIG_T2))  # INT16
        self.cal_t3 = int(self._readS16(BMP280_DIG_T3))  # INT16
        self.cal_p1 = int(self._readU16(BMP280_DIG_P1))  # UINT16
        self.cal_p2 = int(self._readS16(BMP280_DIG_P2))  # INT16
        self.cal_p3 = int(self._readS16(BMP280_DIG_P3))  # INT16
        self.cal_p4 = int(self._readS16(BMP280_DIG_P4))  # INT16
        self.cal_p5 = int(self._readS16(BMP280_DIG_P5))  # INT16
        self.cal_p6 = int(self._readS16(BMP280_DIG_P6))  # INT16
        self.cal_p7 = int(self._readS16(BMP280_DIG_P7))  # INT16
        self.cal_p8 = int(self._readS16(BMP280_DIG_P8))  # INT16
        self.cal_p9 = int(self._readS16(BMP280_DIG_P9))  # INT16

    def read_raw_data(self, register):
        data = self.i2c.read_i2c_block_data(self.address, register, 3)
        data = self.convert_data(data[0], data[1], data[2])
        return data

    def _compensate_temp(self, raw_temp):
        t1 = (((raw_temp >> 3) - (self.cal_t1 << 1)) * (self.cal_t2) >> 11)
        t2 = (((((raw_temp >> 4) - (self.cal_t1)) * ((raw_temp >> 4) -
                                                     (self.cal_t1))) >> 12) *
              (self.cal_t3)) >> 14
        return t1 + t2

    def read_temperature(self):
        raw_temp = self.read_raw_data(BMP280_TEMPDATA)
        compensated_temp = self._compensate_temp(raw_temp)
        temp = float(((compensated_temp * 5 + 128) >> 8)) / 100
        return temp

    def read_pressure(self):
        raw_temp = self.read_raw_data(BMP280_TEMPDATA)
        compensated_temp = self._compensate_temp(raw_temp)
        raw_pressure = self.read_raw_data(BMP280_PRESSUREDATA)

        p1 = compensated_temp - 128000
        p2 = p1 * p1 * self.cal_p6
        p2 += (p1 * self.cal_p5) << 17
        p2 += self.cal_p4 << 35
        p1 = ((p1 * p1 * self.cal_p3) >> 8) + ((p1 * self.cal_p2) << 12)
        p1 = ((1 << 47) + p1) * (self.cal_p1) >> 33

        if 0 == p1:
            return 0

        p = 1048576 - raw_pressure
        p = (((p << 31) - p2) * 3125) / p1
        p1 = (self.cal_p9 * (int(p) >> 13) * (int(p) >> 13)) >> 25
        p2 = int((self.cal_p8 * p)) >> 19
        p = (int((p + p1 + p2)) >> 8) + ((self.cal_p7) << 4)

        return float(p / 256)

    def read_altitude(self, sealevel_pa=101325.0):
        """Calculates the altitude in meters."""
        # Calculation taken straight from section 3.6 of the datasheet.
        pressure = float(self.read_pressure())
        altitude = 44330.0 * (1.0 - pow(pressure / sealevel_pa, (1.0 / 5.255)))
        return altitude

    def read_sealevel_pressure(self, altitude_m=0.0):
        """Calculates the pressure at sealevel when given a known altitude in
        meters. Returns a value in Pascals."""
        pressure = float(self.read_pressure())
        p0 = pressure / pow(1.0 - altitude_m / 44330.0, 5.255)
        return p0

    @staticmethod
    def convert_data(msb, lsb, xlsb):
        data = ((msb << 8 | lsb) << 8 | xlsb) >> 4
        return data
Exemplo n.º 49
0
Arquivo: SHT21.py Projeto: Miaou/BBB
class SHT21 :
    RHmeasure_noHold = 0xF5
    Tmeasure_noHold  = 0xF3
    RHmeasure_Hold   = 0xE5
    Tmeasure_Hold    = 0xE3
    Soft_Reset       = 0xFE
    Write_Reg        = 0xE6
    Read_Reg         = 0xE7
##############################################################################
##  Experimental register found by looking for each one individually        ##
##  with a 10 seconds wait between each try. CheckCRC says true for all.    ##
    RH_Reg           = 0x05                                                 ##
    T_Reg            = 0x03                                                 ##
##  read_reg?          0x06                                                 ##
##  read_reg           0x07                                                 ##
##  unknown            0x09     result was 6,0,90(constant over time)       ##
##  unknown            0x0F     result was 2,68,32(constant over time)      ##
##  serial number?     0x1A     periodic on 64 bits?                        ##
##  result was      [25, 203, 218, 223, 71, 170, 137, 242, 217, 140, 232    ##
##                  , 120, 231, 86, 128, 122, 7, 151, 248, 59, 252, 255,    ##
##                  232, 120, 54, 99, 129, 75, 30, 92, 80, 126]             ##
##  serial number?     0x1B     same as 0x1A with random shift              ##
##  T_reg?             0xE3     result was 103,88,60(made a new measure?)   ##
##  RH_reg?            0xE5     result was 83,206,146(new measure?)         ##
##  read_reg           0xE6     result was 58,30                            ##
##  read_reg           0xE7     result was 58,30                            ##
##  unknown            0xE9     result was 6,0,90                           ##
##  unknown            0xEF     result was 2,68,32                          ##
##  serial number      0xFA     same as 1A, check sensirion(says 64 bits ID)##
##  serial number?     0xFB     same as 1B                                  ##
##  device ID?         0xFF     check i2c full specs, results seems random  ##
############################1#################################################
    class CRCError(Exception):
        pass

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

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


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

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

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

    def CheckCRC(self, buf):
        poly = 0x131
        crc = 0
        #print buf[2]
        for by in buf:
            crc ^= by
            for i in range(8):
                if crc & 0x80 :
                    crc = (crc << 1)^poly
                else:
                    crc <<= 1
                #print crc
        return crc==0
Exemplo n.º 50
0
class Hardware:

    def __init__(self, leds, pins):
        self.leds = leds
        self.pins = pins
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.leds.values(), GPIO.OUT)

        self.HumidityTemperature = Adafruit_DHT.DHT11

        self.lightAddress = 0x23
        self.lightMode = 0x20
        self.Light = SMBus(1)

        GPIO.setup(self.pins['PIR'], GPIO.IN)
        for pin in self.pins['PIR']:
            GPIO.add_event_detect(pin, GPIO.RISING, callback=self._onPIR)
        self.PIRON = False

        GPIO.setup(self.pins['Sound'], GPIO.IN)
        GPIO.add_event_detect(self.pins['Sound'], GPIO.RISING, callback=self._onSound)
        self.SOUNDON = False

        GPIO.setup(self.pins['Human'], GPIO.IN)
        GPIO.add_event_detect(self.pins['Human'], GPIO.RISING, callback=self._onHuman)
        self.HUMANON = False

    def _set(self, led, state):
        if state:
            GPIO.output(led, GPIO.HIGH)
        else:
            GPIO.output(led, GPIO.LOW)

    def _getHumidityTemperature(self):
        humidity, temperature = Adafruit_DHT.read_retry(self.HumidityTemperature, self.pins['HumidityTemperature'])
        return humidity, temperature

    def _getLight(self):
        reading = self.Light.read_i2c_block_data(self.lightAddress, self.lightMode)
        def convertToNumber(data):
            return (data[1] + (256 * data[0]))/1.2
        return convertToNumber(reading)

    def _onPIR(self, *args):
        self.PIRON = True

    def _getPIR(self):
        if self.PIRON:
            self.PIRON = False
            return 1
        else:
            return 0

    def _onSound(self, *args):
        self.SOUNDON = True

    def _getSound(self):
        if self.SOUNDON:
            self.SOUNDON = False
            return 1
        else:
            return 0

    def _getTemperature(self):
        reading = self.Temperature.read_word_data(self.temperatureAddress, 0) & 0xFFFF
        reading = ((reading << 8) & 0xFF00) + (reading >> 8)
        return (reading / 32.0) / 8.0

    def _onHuman(self, *args):
        self.HUMANON = True

    def _getHuman(self):
        if self.HUMANON:
            self.HUMANON = False
            return 1
        else:
            return 0

    def update(self, booked=None, occupied=None):
        if booked:
            self._set(self.leds['YELLOW'], booked)
            self._set(self.leds['GREEN'], (not booked))
        if occupied:
            self._set(self.leds['YELLOW'], occupied)
            self._set(self.leds['GREEN'], (not occupied))
        # Sets the appropriate lighting/screen based on the booked and occupied status

    def download(self):
        data = {}
        data['Humidity'], data['Temperature'] = self._getHumidityTemperature()
        data['Light'] = self._getLight()
        data['Sound'] = self._getSound()
        data['PIR'] = self._getPIR()
        data['Human'] = self._getHuman()
        print(data)
        return data
bus.write_byte_data(ADDR, CTRL_REG1, newSetting)
# Enable event flags
bus.write_byte_data(ADDR, PT_DATA_CFG, 0x07)
# Toggel One Shot
setting = bus.read_byte_data(ADDR, CTRL_REG1)
if (setting & 0x02) == 0:
    bus.write_byte_data(ADDR, CTRL_REG1, (setting | 0x02))
# Read sensor data
print "Waiting for data..."
status = bus.read_byte_data(ADDR,0x00)
while (status & 0x08) == 0:
#print bin(status)
    status = bus.read_byte_data(ADDR,0x00)
    time.sleep(0.5)
print "Reading sensor data..."
p_data = bus.read_i2c_block_data(ADDR,0x01,3)
t_data = bus.read_i2c_block_data(ADDR,0x04,2)
status = bus.read_byte_data(ADDR,0x00)
print "status: "+bin(status)
p_msb = p_data[0]
p_csb = p_data[1]
p_lsb = p_data[2]
t_msb = t_data[0]
t_lsb = t_data[1]
pressure = (p_msb << 10) | (p_csb << 2) | (p_lsb >> 6)
p_decimal = ((p_lsb & 0x30) >> 4)/4.0
celsius = t_msb + (t_lsb >> 4)/16.0
fahrenheit = (celsius * 9)/5 + 32
print "Pressure and Temperature at "+time.strftime('%m/%d/%Y %H:%M:%S%z')
print str(pressure+p_decimal)+" Pa"
print str(celsius)+deg+"C"
Exemplo n.º 52
0
class HTAngle:
    def __init__(self, bus_no, address):
        self.bus = SMBus(bus_no)
        self.address = address

        self.angle = 0  # angle, degrees(datetime.utcnow().strftime('%H-%M-%S.%f')[:-3]0 - 359)
        self.acc_angle = 0  # accumulated angle, degrees(-2147483648 - 2147483647)
        self.rpm = 0  # rotations per minute (-1000 to 1000)

        self.current_data1_bit = False
        self.current_data2_bit = False
        self.last_data1_bit = False
        self.last_data2_bit = False

        self.update()

    def set_mode(self, mode):
        self.bus.write_byte_data(self.address, 0x41, mode)

    def get_mode(self):
        return self.bus.read_byte_data(self.address, 0x41)

    def reset(self):
        # reset accumulated angle
        self.set_mode(MODE_RESET)
        time.sleep(0.1)

        # calibrate angle
        self.set_mode(MODE_CALIBRATE)
        time.sleep(0.1)

        self.update()

    def update(self):
        ########################################################################
        ### * ERROR FILTERING!                                              ###
        ### (1) data = 0xff                                                  ###
        ### (2) data[1]의 최상위 비트 반전 (data[0]의 최상위비트)                 ###
        ### (3) data[2]의 최상위 비트 반전                                      ###
        ########################################################################
        isError = True
        while isError:
            try:
                data = self.bus.read_i2c_block_data(self.address, 0x41, 10)
                # error filtering (1)
                if data[1] == data[2] == data[3] == data[4] == data[5] == data[
                        6] == data[7] == data[8] == 0xff:
                    isError = True
                    time.sleep(0.0001)
                    continue
                if data[2] == 0xff:
                    isError = True
                    time.sleep(0.0001)
                    continue
                # not error
                else:
                    isError = False
            except (TypeError, OSError) as e:
                print("update error: {0}".format(str(e)))
                isError = True
                time.sleep(0.0001)

        # error filtering (3)
        self.current_data1_bit = True if data[1] & 0x20 == 0x20 else False
        self.current_data2_bit = True if data[2] & 0x80 == 0x80 else False
        if self.last_data1_bit and self.last_data2_bit:
            if self.current_data1_bit and not self.current_data2_bit:
                data[2] = data[2] | 0x80
        self.last_data1_bit = self.current_data1_bit
        self.last_data2_bit = self.current_data2_bit

        # angle
        self.angle = (data[1] & 0x7f) * 2 + (data[2] & 0x01) + (
            (data[2] & 0x80) << 1)  # error filtering (2)

        # accumulated angle
        acc = (((data[3] & 0x7f) + (data[4] & 0x80)) * 0x1000000)\
              + (((data[4] & 0x7f) + (data[5] & 0x80)) * 0x10000)\
              + (((data[5] & 0x7f) + (data[6] & 0x80)) * 0x100)\
              + ((data[6] & 0x7f) + (data[7] & 0x80))

        # convert to signed
        if acc > 0x7fffffff:
            self.acc_angle = (0x100000000 - acc) * (-1)
        else:
            self.acc_angle = acc

        # rpm
        rpm = (data[7] & 0x7f) * 0x100 + (data[8] & 0x7f) + (data[9] & 0x80)

        # convert to signed
        if rpm > 0x3fff:
            self.rpm = (0x8000 - rpm) * (-1)
        else:
            self.rpm = rpm
        return (self.angle, self.acc_angle, self.rpm)
Exemplo n.º 53
0
class MS5611:
    """Driver for reading temperature/pressure MS5611 Pressure Sensor."""
    
    def __init__(self, bus = 1, i2c = 0x76, elevation = 0):
        """Initialize the Driver.

        Default bus is 1.  If you have a Rev 1 RPi then you will need to use bus 0.
        A bus object can also be passed in if you are sharing it among other modules
        
        Arguments (All optional):
        bus -- 0, 1, or a bus object
        i2c -- I2C address
        elevation -- Elevation in meters"""
        
        if(bus == 0 or bus == 1):
            self.bus = SMBus(bus)
        else:
            self.bus = bus
        self.i2c = i2c
        self.elevation = elevation


    def setElevation(self, elevation):
        self.elevation = elevation


    def setElevationFt(self, elevation):
        self.elevation = elevation / 3.2808


    def setI2c(self, i2c):
        self.i2c = i2c


    def read(self):
        ## Get raw pressure
        self.bus.write_byte(self.i2c, 0x48)
        time.sleep(0.05)

        D1 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D1 = D1[0] * 65536 + D1[1] * 256.0 + D1[2]
        time.sleep(0.05)

        ## Get raw temperature
        self.bus.write_byte(self.i2c, 0x58)
        time.sleep(0.05)
        D2 = self.bus.read_i2c_block_data(self.i2c, 0x00)
        D2 = D2[0] * 65536 + D2[1] * 256.0 + D2[2]
        time.sleep(0.05)

        
        ## Read Constants from Sensor
        if hasattr(self, 'C1'):
            C1 = self.C1
        else:
            C1 = self.bus.read_i2c_block_data(self.i2c, 0xA2) #Pressure Sensitivity
            C1 = C1[0] * 256.0 + C1[1]
            self.C1 = C1
            time.sleep(0.05)

        if hasattr(self, 'C2'):
            C2 = self.C2
        else:
            C2 = self.bus.read_i2c_block_data(self.i2c, 0xA4) #Pressure Offset
            C2 = C2[0] * 256.0 + C2[1]
            self.C2 = C2
            time.sleep(0.05)

        if hasattr(self, 'C3'):
            C3 = self.C3
        else:
            C3 = self.bus.read_i2c_block_data(self.i2c, 0xA6) #Temperature coefficient of pressure sensitivity
            C3 = C3[0] * 256.0 + C3[1]
            self.C3 = C3
            time.sleep(0.05)

        if hasattr(self, 'C4'):
            C4 = self.C4
        else:
            C4 = self.bus.read_i2c_block_data(self.i2c, 0xA8) #Temperature coefficient of pressure offset
            C4 = C4[0] * 256.0 + C4[1]
            self.C4 = C4
            time.sleep(0.05)

        if hasattr(self, 'C5'):
            C5 = self.C5
        else:
            C5 = self.bus.read_i2c_block_data(self.i2c, 0xAA) #Reference temperature
            C5 = C5[0] * 256.0 + C5[1]
            self.C5 = C5
            time.sleep(0.05)

        if hasattr(self, 'C6'):
            C6 = self.C6
        else:
            C6 = self.bus.read_i2c_block_data(self.i2c, 0xAC) #Temperature coefficient of the temperature
            C6 = C6[0] * 256.0 + C6[1]
            self.C6 = C6
            time.sleep(0.05)

        
        ## These are the calculations provided in the datasheet for the sensor.
        dT = D2 - C5 * 2**8
        TEMP = 2000 + dT * C6 / 2**23

        ## Set Values to class to be used elsewhere
        self.tempC = TEMP/100.0
        self.tempF = TEMP/100.0 * 9.0/5 + 32
        self.tempK = TEMP/100.0 + 273.15

        ## These calculations are all used to produce the final pressure value
        OFF = C2 * 2**16 + (C4 * dT) / 2**7
        SENS = C1 * 2**15 + (C3 * dT) / 2**8
        P = (D1 * SENS / 2**21 - OFF) / 2**15
        self.pressure = P/100.0

        ## Calculate an offset for the pressure.  This is required so that the readings are correct.
        ##   Equation can be found here: http://en.wikipedia.org/wiki/Barometric_formula
        altOffset = math.exp( (-9.80665 * 0.0289644 * self.elevation) / (8.31432 * self.tempK) )
        self.pressureAdj = ( P/altOffset ) / 100.0 

    def getTempC(self):
        return self.tempC

    def getTempF(self):
        return self.tempF

    def getPressure(self):
        return self.pressure

    def getPressureAdj(self):
        return self.pressureAdj

    def getBus(self):
        return self.bus

    def printResults(self):
        print "Temperature:", round(self.tempC, 2), "C"
        print "            ", round(self.tempF, 2), "F"

        print "Pressure Absolute:", round(self.pressure, 2), "hPa"
        print "         Adjusted:", round(self.pressureAdj, 2), "hPa"
        print "         Adjusted:", round(self.convert2In(self.pressureAdj), 2), "in"

    def convert2In(self, pressure):
        return pressure * 0.0295301
Exemplo n.º 54
0
## Import Libraries that let python talk to I2C devices
from smbus import SMBus

## Initialize the bus.  (If you have a Rev 2 Raspberry Pi the 0 needs to be changed to a 1)
bus = SMBus(0)

## This writes the command to the Sensor to calculate the digital value of pressure.  (This is a raw value and will
#       be used in a calculation later on in the script to get the actual real pressure.)
bus.write_byte(0x76, 0x48)
time.sleep(0.05)

## This command reads the data that we just calculated on the sensor
##  I had to use the read_i2c_block_data rather than the read_word or read_byte because the values being returned by the
#       sensor were 24 bit and was being truncated by the other read methods.  Reading the whole data block was the only way
#       that I knew to get all of the data.
D1 = bus.read_i2c_block_data(0x76, 0x00)
time.sleep(0.05)

## This is much like above only it is getting the raw temperature.
bus.write_byte(0x76, 0x58)
time.sleep(0.05)
D2 = bus.read_i2c_block_data(0x76, 0x00)
time.sleep(0.05)

## The data being read in blocks are in an array in 8 bit pieces, so we need to convert the first 24 bits into decimal,
#       which is what this statement does.
D1 = D1[0] * 65536 + D1[1] * 256.0 + D1[2]
D2 = D2[0] * 65536 + D2[1] * 256.0 + D2[2]

## The MS6511 Sensor stores 6 values in the EPROM memory that we need in order to calculate the actual temperature and pressure
## These values are calculated/stored at the factory when the sensor is calibrated.
Exemplo n.º 55
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])
class HTAngle:
    def __init__(self, bus_no, address):
        self.bus = SMBus(bus_no)
        self.address = address

        self.angle = 0              # angle, degrees(0 - 359)
        self.acc_angle = 0          # accumulated angle, degrees(-2147483648 - 2147483647)
        self.rpm = 0                # rotations per minute (-1000 to 1000)

        self.update()

    def set_mode(self, mode):
        self.bus.write_byte_data(self.address, 0x41, mode)

    def get_mode(self):
        return self.bus.read_byte_data(self.address, 0x41)

    def reset(self):
        # reset accumulated angle
        self.set_mode(MODE_RESET)
        time.sleep(0.1)

        # calibrate angle
        self.set_mode(MODE_CALIBRATE)
        time.sleep(0.1)

        self.update()

    def update(self):
        isError = True
        while isError:
            try:
                data = self.bus.read_i2c_block_data(self.address, 0x41, 10)
                isError = False
            except OSError as e:
                print(e)
                isError = True

        # error filtering
        if data[1] == data[2] == data[3] == data[4] == data[5] == data[6] == data[7] == data[8] == 0xff:
            return (self.angle, self.acc_angle, self.rpm), True

        # angle
        self.angle = (data[1] & 0xff) * 2 + (data[2] & 0x01) + ((data[2] & 0x80) << 1)

        # accumulated angle
        acc = (((data[3] & 0x7f) + (data[4] & 0x80)) * 0x1000000)\
              + (((data[4] & 0x7f) + (data[5] & 0x80)) * 0x10000)\
              + (((data[5] & 0x7f) + (data[6] & 0x80)) * 0x100)\
              + ((data[6] & 0x7f) + (data[7] & 0x80))

        # convert to signed
        if acc > 0x7fffffff:
            self.acc_angle = (0x100000000 - acc) * (-1)
        else:
            self.acc_angle = acc

        # rpm
        rpm = (data[7] & 0x7f) * 0x100 + (data[8] & 0x7f) + (data[9] & 0x80)

        # convert to signed
        if rpm > 0x3fff:
            self.rpm = (0x8000 - rpm) * (-1)
        else:
            self.rpm = rpm
        return (self.angle, self.acc_angle, self.rpm), False
Exemplo n.º 57
0
class Cap1xxx():
    supported = [PID_CAP1208, PID_CAP1188, PID_CAP1166]
    number_of_inputs = 8
    number_of_leds   = 8
  
    def __init__(self, i2c_addr=DEFAULT_ADDR, i2c_bus=1, alert_pin=-1, reset_pin=-1, on_touch=None, skip_init=False):
        if on_touch == None:
            on_touch = [None] * self.number_of_inputs

        self.async_poll = None
        self.i2c_addr   = i2c_addr
        self.i2c        = SMBus(i2c_bus)
        self.alert_pin  = alert_pin
        self.reset_pin  = reset_pin
        self._delta     = 50

        GPIO.setmode(GPIO.BCM)
        if not self.alert_pin == -1:
            GPIO.setup(self.alert_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)

        if not self.reset_pin == -1:
            GPIO.setup(self.reset_pin,  GPIO.OUT)
            GPIO.setup(self.reset_pin,  GPIO.LOW)
            GPIO.output(self.reset_pin, GPIO.HIGH)
            time.sleep(0.01)
            GPIO.output(self.reset_pin, GPIO.LOW)

        self.handlers = {
            'press'   : [None] * self.number_of_inputs,
            'release' : [None] * self.number_of_inputs,
            'held'    : [None] * self.number_of_inputs
        }

        self.touch_handlers    = on_touch
        self.last_input_status = [False]  * self.number_of_inputs
        self.input_status      = ['none'] * self.number_of_inputs
        self.input_delta       = [0] * self.number_of_inputs
        self.input_pressed     = [False]  * self.number_of_inputs
        self.repeat_enabled    = 0b00000000
        self.release_enabled   = 0b11111111
        
        self.product_id = self._get_product_id()

        if not self.product_id in self.supported:
            raise Exception("Product ID {} not supported!".format(self.product_id))

        if skip_init:
            return

        # Enable all inputs with interrupt by default
        self.enable_inputs(0b11111111)
        self.enable_interrupts(0b11111111)

        # Disable repeat for all channels, but give
        # it sane defaults anyway
        self.enable_repeat(0b00000000)
        self.enable_multitouch(True)

        self.set_hold_delay(210)
        self.set_repeat_rate(210)

        # Tested sane defaults for various configurations
        self._write_byte(R_SAMPLING_CONFIG, 0b00001000) # 1sample per measure, 1.28ms time, 35ms cycle
        self._write_byte(R_SENSITIVITY,     0b01100000) # 2x sensitivity
        self._write_byte(R_GENERAL_CONFIG,  0b00111000)
        self._write_byte(R_CONFIGURATION2,  0b01100000)
        self.set_touch_delta(10)

        atexit.register(self.stop_watching)

    def get_input_status(self):
        """Get the status of all inputs.
        Returns an array of 8 boolean values indicating
        whether an input has been triggered since the
        interrupt flag was last cleared."""
        touched = self._read_byte(R_INPUT_STATUS)
        threshold = self._read_block(R_INPUT_1_THRESH, self.number_of_inputs)
        delta = self._read_block(R_INPUT_1_DELTA, self.number_of_inputs)
        #status = ['none'] * 8
        for x in range(self.number_of_inputs):
            if (1 << x) & touched:
                status = 'none'
                _delta = self._get_twos_comp(delta[x]) 
                #threshold = self._read_byte(R_INPUT_1_THRESH + x)
                # We only ever want to detect PRESS events
                # If repeat is disabled, and release detect is enabled
                if _delta >= threshold[x]: # self._delta:
                    self.input_delta[x] = _delta
                    #  Touch down event
                    if self.input_status[x] in ['press','held']:
                        if self.repeat_enabled & (1 << x):
                            status = 'held'
                    if self.input_status[x] in ['none','release']:
                        if self.input_pressed[x]:
                            status = 'none'
                        else:
                            status = 'press'
                else:
                    # Touch release event
                    if self.release_enabled & (1 << x) and not self.input_status[x] == 'release':
                        status = 'release'
                    else:
                        status = 'none'

                self.input_status[x] = status
                self.input_pressed[x] = status in ['press','held','none']
            else:
                self.input_status[x] = 'none'
                self.input_pressed[x] = False
        return self.input_status

    def _get_twos_comp(self,val):
        if ( val & (1<< (8 - 1))) != 0:
            val = val - (1 << 8)
        return val
        
    def clear_interrupt(self):
        """Clear the interrupt flag, bit 0, of the
        main control register"""
        main = self._read_byte(R_MAIN_CONTROL)
        main &= ~0b00000001
        self._write_byte(R_MAIN_CONTROL, main)

    def _interrupt_status(self):
        if self.alert_pin == -1:
            return self._read_byte(R_MAIN_CONTROL) & 1
        else:
            return not GPIO.input(self.alert_pin)

    def wait_for_interrupt(self, timeout=100):
        """Wait for, interrupt, bit 0 of the main
        control register to be set, indicating an
        input has been triggered."""
        start = self._millis()
        while True:
            status = self._interrupt_status() # self._read_byte(R_MAIN_CONTROL)
            if status:
                return True
            if self._millis() > start + timeout:
                return False
            time.sleep(0.005)

    def on(self, channel=0, event='press', handler=None):
        self.handlers[event][channel] = handler
        self.start_watching()
        return True

    def start_watching(self):
        if not self.alert_pin == -1:
            try:
                GPIO.add_event_detect(self.alert_pin, GPIO.FALLING, callback=self._handle_alert, bouncetime=1)
                self.clear_interrupt()
            except:
                pass
            return True

        if self.async_poll == None:
            self.async_poll = AsyncWorker(self._poll)
            self.async_poll.start()
            return True
        return False

    def stop_watching(self):
        if not self.alert_pin == -1:
            GPIO.remove_event_detect(self.alert_pin)

        if not self.async_poll == None:
            self.async_poll.stop()
            self.async_poll = None
            return True
        return False

    def set_touch_delta(self, delta):
        self._delta = delta

    def auto_recalibrate(self, value):
        self._change_bit(R_GENERAL_CONFIG, 3, value)
        
    def filter_analog_noise(self, value):
        self._change_bit(R_GENERAL_CONFIG, 4, not value)
        
    def filter_digital_noise(self, value):
        self._change_bit(R_GENERAL_CONFIG, 5, not value)

    def set_hold_delay(self, ms):
        """Set time before a press and hold is detected,
        Clamps to multiples of 35 from 35 to 560"""
        repeat_rate = self._calc_touch_rate(ms)
        input_config = self._read_byte(R_INPUT_CONFIG2)
        input_config = (input_config & ~0b1111) | repeat_rate
        self._write_byte(R_INPUT_CONFIG2, input_config)

    def set_repeat_rate(self, ms):
        """Set repeat rate in milliseconds, 
        Clamps to multiples of 35 from 35 to 560"""
        repeat_rate = self._calc_touch_rate(ms)
        input_config = self._read_byte(R_INPUT_CONFIG)
        input_config = (input_config & ~0b1111) | repeat_rate
        self._write_byte(R_INPUT_CONFIG, input_config)

    def _calc_touch_rate(self, ms):
        ms = min(max(ms,0),560)
        scale = int((round(ms / 35.0) * 35) - 35) / 35
        return int(scale)

    def _handle_alert(self, pin=-1):
        inputs = self.get_input_status()
        self.clear_interrupt()
        for x in range(self.number_of_inputs):
            self._trigger_handler(x, inputs[x])

    def _poll(self):
        """Single polling pass, should be called in
        a loop, preferably threaded."""
        if self.wait_for_interrupt():
            self._handle_alert()

    def _trigger_handler(self, channel, event):
        if event == 'none':
            return
        if callable(self.handlers[event][channel]):
            try:
                self.handlers[event][channel](CapTouchEvent(channel, event, self.input_delta[channel]))
            except TypeError:
                self.handlers[event][channel](channel, event)

    def _get_product_id(self):
        return self._read_byte(R_PRODUCT_ID)

    def enable_multitouch(self, en=True):
        """Toggles multi-touch by toggling the multi-touch
        block bit in the config register"""
        ret_mt = self._read_byte(R_MTOUCH_CONFIG)
        if en:
            self._write_byte(R_MTOUCH_CONFIG, ret_mt & ~0x80)
        else:
            self._write_byte(R_MTOUCH_CONFIG, ret_mt | 0x80 )

    def enable_repeat(self, inputs):
        self.repeat_enabled = inputs
        self._write_byte(R_REPEAT_EN, inputs)

    def enable_interrupts(self, inputs):
        self._write_byte(R_INTERRUPT_EN, inputs)

    def enable_inputs(self, inputs):
        self._write_byte(R_INPUT_ENABLE, inputs)

    def _write_byte(self, register, value):
        self.i2c.write_byte_data(self.i2c_addr, register, value)

    def _read_byte(self, register):
        return self.i2c.read_byte_data(self.i2c_addr, register)

    def _read_block(self, register, length):
        return self.i2c.read_i2c_block_data(self.i2c_addr, register, length)

    def _millis(self):
        return int(round(time.time() * 1000))

    def _set_bit(self, register, bit):
        self._write_byte( register, self._read_byte(register) | (1 << bit) )

    def _clear_bit(self, register, bit):
        self._write_byte( register, self._read_byte(register) & ~(1 << bit ) )

    def _change_bit(self, register, bit, state):
        if state:
            self._set_bit(register, bit)
        else:
            self._clear_bit(register, bit)

    def _change_bits(self, register, offset, size, bits):
        original_value = self._read_byte(register)
        for x in range(size):
            original_value &= ~(1 << (offset+x))
        original_value |= (bits << offset)
        self._write_byte(register, original_value)

    def __del__(self):
        self.stop_watching()
Exemplo n.º 58
0
bus = 1
address = 0x48
duration = 10  # seconds
filename = "test.wav"

# Prepare
file = wave.open(filename, 'w')
file.setnchannels(1)  # Mono
file.setframerate(860)  # Frames per second
file.setsampwidth(2)  # 2 bytes per frame
adc = SMBus(bus)

# Reset
adc.write_byte(0x00, 0x06)
time.sleep(0.5)

# Set configuration
# 1 101 111 0 = de
# 111 0 1 0 00 = e8
adc.write_i2c_block_data(address, 0x01, [0xde, 0xe8])
time.sleep(0.5)

# Record input
for frame in range(int(duration * 860)):
    data = adc.read_i2c_block_data(address, 0x00, 2)
    value = data[0] * 256 + data[1]
    if value > 32767: value -= 65535
    print(value)
    file.writeframesraw(struct.pack("<h", value))
    time.sleep(1 / 860)
Exemplo n.º 59
0
#!/usr/bin/python

from smbus import SMBus
from time import sleep
from ctypes import c_short
#Pressure and Temprature
addr = 0x77
oversampling = 3        # 0..3
bus = SMBus(1);         # 0 for R-Pi Rev. 1, 1 for Rev. 2
def get_short(data, index): # return two bytes from data as a signed 16-bit value
        return c_short((data[index] << 8) + data[index + 1]).value
def get_ushort(data, index): # return two bytes from data as an unsigned 16-bit value
        return (data[index] << 8) + data[index + 1]
(chip_id, version) = bus.read_i2c_block_data(addr, 0xD0, 2)
#print "Chip Id:", chip_id, "Version:", version
#print
#print "Reading calibration data..."
# Read whole calibration EEPROM data
cal = bus.read_i2c_block_data(addr, 0xAA, 22)
# Convert byte data to word values
ac1 = get_short(cal, 0)
ac2 = get_short(cal, 2)
ac3 = get_short(cal, 4)
ac4 = get_ushort(cal, 6)
ac5 = get_ushort(cal, 8)
ac6 = get_ushort(cal, 10)
b1 = get_short(cal, 12)
b2 = get_short(cal, 14)
mb = get_short(cal, 16)
mc = get_short(cal, 18)
md = get_short(cal, 20)
Exemplo n.º 60
0
class SHT31D:
    def __init__(self, i2cAddr):
        self.address = i2cAddr
        self.bus = SMBus(1)
        time.sleep(0.05)

    def readTemperatureAndHumidity(self):
        self.writeCommand(SHT31DConstant.SHT31_MEAS_HIGHREP)
        time.sleep(0.015)
        TempMSB, TempLSB, TempCRC, HumMSB, HumLSB, HumCRC = self.readData(
            SHT31DConstant.SHT31_MEAS_HIGHREP)
        STemp = TempMSB * 16 * 16 + TempLSB
        SHum = HumMSB * 16 * 16 + HumLSB
        # print TempCRC
        if TempCRC != self.CRC8([TempMSB, TempLSB]):
            TC = "nan"
        else:
            TC = -45 + 175 * STemp / float(2**16 - 1)
        # print HumCRC
        if HumCRC != self.CRC8([HumMSB, HumLSB]):
            RH = "nan"
        else:
            RH = 100 * SHum / float(2**16 - 1)
        return (TC, RH)
        # return
    def readTemperature(self):
        (TC, RH) = self.readTemperatureAndHumidity()
        return TC

    def readHumidity(self):
        (TC, RH) = self.readTemperatureAndHumidity()
        return RH

    def clearStatus(self):
        self.writeCommand(SHT31DConstant.SHT31_CLEARSTATUS)

    def readStatus(self):
        self.writeCommand(SHT31DConstant.SHT31_READSTATUS)
        StatusMSB, StatusLSB, StatusCRC = self.readData(
            SHT31DConstant.SHT31_READSTATUS, 3)
        if StatusCRC != self.CRC8([StatusMSB, StatusLSB]):
            return 'nan'
        else:
            return StatusMSB << 8 | StatusLSB

    def heaterEnable(self):
        self.writeCommand(SHT31DConstant.SHT31_HEATEREN)

    def heaterDisable(self):
        self.writeCommand(SHT31DConstant.SHT31_HEATERDIS)

    def softReset(self):
        self.writeCommand(SHT31DConstant.SHT31_SOFTRESET)

    def writeCommand(self, cmd):
        self.bus.write_word_data(self.address, cmd >> 8, cmd & 0xFF)

    def readData(self, cmd, numBytes=6):
        return self.bus.read_i2c_block_data(self.address, cmd, numBytes)

    def CRC8(self, buffer):
        """ Polynomial 0x31 (x8 + x5 +x4 +1) """

        polynomial = 0x31
        crc = 0xFF

        index = 0
        # print buffer
        for index in range(0, len(buffer)):
            crc ^= int(buffer[index])
            for i in range(8, 0, -1):
                if crc & 0x80:
                    crc = (crc << 1) ^ polynomial
                else:
                    crc = (crc << 1)
        # print crc & 0xFF
        return crc & 0xFF