예제 #1
0
class ad7606():
    try:
        start_acq_fd = open("/sys/class/gpio/gpio145/value", 'w', 0)
    except IOError as e:
        print("Error opening start acquire gpio pin: %s" % e)
        raise

    def __init__(self, dev):
        self.dev = SpiDev()
        try:
            self.dev.open(3, dev)
            self.dev.mode = 2
        except IOError as e:
            print("Error opening /dev/spidev3.%d: %s" % (dev, e))
            raise

    def trigger_acquire(self):
        self.start_acq_fd.write(b'1')
        self.start_acq_fd.write(b'0')

    def read(self):
        self.trigger_acquire()
        buf = self.dev.readbytes(16)
        samples = [0, 0, 0, 0, 0, 0, 0, 0]
        for i in xrange(8):
            samples[i] = buf[2 * i] << 8 | buf[2 * i + 1] << 0
        return samples
예제 #2
0
class ad7606():
    try:
        start_acq_fd = open("/sys/class/gpio/gpio145/value", 'w', 0)
    except IOError as e:
        print("Error opening start acquire gpio pin: %s" % e)
        raise

    def __init__(self, dev):
        self.dev = SpiDev()
        try:
            self.dev.open(3,dev)
            self.dev.mode = 2
        except IOError as e:
            print("Error opening /dev/spidev3.%d: %s" % (dev, e))
            raise

    def trigger_acquire(self):
        self.start_acq_fd.write(b'1')
        self.start_acq_fd.write(b'0')

    def read(self):
        self.trigger_acquire()
        buf = self.dev.readbytes(16)
        samples = [0,0,0,0,0,0,0,0]
        for i in xrange(8):
            samples[i] = buf[2*i] << 8 | buf[2*i+1] << 0
        return samples
예제 #3
0
class O2Sensor(AbstractSensor):
    def generateCalibCurve(self):
        calibFilename = "callibCurve.csv"
        calibFile = open(path.dirname(__file__) + "/" + calibFilename, 'r')
        reader = csv.reader(calibFile)
        xVals = []
        yVals = []
        for row in reader:
            yVals.append(float(row[0]))
            xVals.append(float(row[1]))
        calibFile.close()
        self.calibF = interp1d(xVals, yVals)
        self.calibC = 92.8009950249
        self.maxOut = max(yVals)

    def __init__(self):
        AbstractSensor.__init__(self)
        self.measurements = {
            "O2": [-1, "%"],
            "O2voltage": [-1, "V"],
        }
        self._spi = SpiDev(0, 0)
        self._CS = gpiozero.DigitalOutputDevice(5, initial_value=True)
        #self._MISO = gpiozero.DigitalInputDevice(9)
        self._spi.open(0, 0)
        self._spi.max_speed_hz = 500
        self._spi.no_cs = True
        self.generateCalibCurve()

    def reset(self):
        time.sleep(0.01)

    def poll(self):
        self._CS.value = False
        time.sleep(0.09)
        res = self._spi.readbytes(3)
        self._CS.value = True
        res[0] &= 0x1F
        resval = 0
        for i in range(3):
            resval += res[i] << (2 - i) * 8
        if res[0] & 0x10:
            resval = 0x0FFFFF - resval - 1
        resval = resval / float(0x0FFFFF) * 3.3
        self.measurements["O2voltage"][0] = resval
        try:
            concentration = float(self.calibF(resval * self.calibC).item(0))
            self.measurements["O2"][0] = concentration
        except:
            self.measurements["O2"][0] = self.maxOut
예제 #4
0
class CpPhy(object):
	# Profibus baud-rates
	PB_PHY_BAUD_9600	= 0
	PB_PHY_BAUD_19200	= 1
	PB_PHY_BAUD_45450	= 2
	PB_PHY_BAUD_93750	= 3
	PB_PHY_BAUD_187500	= 4
	PB_PHY_BAUD_500000	= 5
	PB_PHY_BAUD_1500000	= 6
	PB_PHY_BAUD_3000000	= 7
	PB_PHY_BAUD_6000000	= 8
	PB_PHY_BAUD_12000000	= 9

	# RTS mode
	PB_PHY_RTS_ALWAYS_LO	= 0
	PB_PHY_RTS_ALWAYS_HI	= 1
	PB_PHY_RTS_SENDING_HI	= 2
	PB_PHY_RTS_SENDING_LO	= 3

	# GPIO numbers (BCM)
	GPIO_RESET		= 17
	GPIO_IRQ		= 27
	GPIO_SS			= 8
	GPIO_MISO		= 9
	GPIO_MOSI		= 10
	GPIO_SCK		= 11

	baud2id = {
		9600		: PB_PHY_BAUD_9600,
		19200		: PB_PHY_BAUD_19200,
		45450		: PB_PHY_BAUD_45450,
		93750		: PB_PHY_BAUD_93750,
		187500		: PB_PHY_BAUD_187500,
		500000		: PB_PHY_BAUD_500000,
		1500000		: PB_PHY_BAUD_1500000,
		3000000		: PB_PHY_BAUD_3000000,
		6000000		: PB_PHY_BAUD_6000000,
		12000000	: PB_PHY_BAUD_12000000,
	}

	def __init__(self, device=0, chipselect=0, debug=False):
		self.device = device
		self.chipselect = chipselect
		self.debug = debug

		try:
			try:
				# Initialize GPIOs
				GPIO.setmode(GPIO.BCM) # Use Broadcom numbers
				GPIO.setwarnings(False)
				GPIO.setup(self.GPIO_RESET, GPIO.OUT, initial=GPIO.LOW)
				GPIO.setup(self.GPIO_IRQ, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
				GPIO.add_event_detect(self.GPIO_IRQ, GPIO.RISING)
				time.sleep(0.05)
			except RuntimeError as e:
				raise PhyError("Failed to initialize GPIOs: %s" %\
					str(e))

			# Initialize SPI
			try:
				self.spi = SpiDev()
				self.spi.open(device, chipselect)
			except IOError as e:
				raise PhyError("Failed to open SPI device %d.%d: %s" %\
					(device, chipselect, str(e)))
			try:
				self.spi.mode = 0;
				self.spi.bits_per_word = 8;
				self.spi.cshigh = False
				self.spi.lsbfirst = False
				self.spi.max_speed_hz = 200000;
			except IOError as e:
				try:
					self.spi.close()
					self.spi = None
				except:
					pass
				raise PhyError("Failed to configure SPI device %d.%d: %s" %\
					(device, chipselect, str(e)))

			# Get the controller out of hardware reset
			GPIO.output(self.GPIO_RESET, GPIO.HIGH)
			time.sleep(0.2)

			# Send a software reset
			self.sendReset()
			# Upload default config
			self.profibusSetPhyConfig()
		except:
			GPIO.cleanup()
			raise

	def cleanup(self):
		self.spi.close()
		self.spi = None
		GPIO.cleanup()

	# Poll for received packet.
	# timeout => In seconds. 0 = none, Negative = unlimited.
	def poll(self, timeout=0):
		limit = TimeLimited(timeout)
		while GPIO.event_detected(self.GPIO_IRQ):
			if limit.exceed():
				return None
			limit.sleep(0.001)
		limit.add(0.5)
		while not limit.exceed():
			fc = self.spi.readbytes(1)[0]
			if fc != CpPhyMessage.RPI_PACK_NOP:
				break
		else:
			return None
		reply = [ fc ]
		reply.extend(self.spi.readbytes(CpPhyMessage.RASPI_PACK_HDR_LEN - 1))
		payloadLen = reply[1] & 0xFF
		if payloadLen:
			reply.extend(self.spi.readbytes(payloadLen))
		message = CpPhyMessage(0)
		message.setRawData(reply)
		if self.debug:
			print("[PHY] recv msg:", message)
		return message

	def __sendMessage(self, message):
		if self.debug:
			print("[PHY] send msg:", message)
		self.spi.writebytes(message.getRawData())

	def sendReset(self):
		self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_RESET))
		reply = self.poll(timeout=-1)
		if reply.fc != CpPhyMessage.RPI_PACK_ACK:
			raise PhyError("Failed to reset PHY")

	def profibusSetPhyConfig(self, baudrate=19200,
				 rxTimeoutMs=100,
				 bitErrorChecks=True,
				 rtsMode=PB_PHY_RTS_SENDING_HI):
		try:
			baudID = self.baud2id[baudrate]
		except KeyError:
			raise PhyError("Invalid baud-rate")
		if rxTimeoutMs < 1 or rxTimeoutMs > 255:
			raise PhyError("Invalid RX timeout")
		payload = [ baudID,
			    rxTimeoutMs,
			    1 if bitErrorChecks else 0,
			    rtsMode & 0xFF ]
		message = CpPhyMessage(CpPhyMessage.RPI_PACK_SETCFG, payload)
		self.__sendMessage(message)
		reply = self.poll(timeout=-1)
		if reply.fc != CpPhyMessage.RPI_PACK_ACK:
			raise PhyError("Failed to upload config")

	def profibusSend_SDN(self, telegramData):
		self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SDN,
						telegramData))

	def profibusSend_SRD(self, telegramData):
		self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SRD,
						telegramData))
예제 #5
0
class CpPhy(object):
    # Profibus baud-rates
    PB_PHY_BAUD_9600 = 0
    PB_PHY_BAUD_19200 = 1
    PB_PHY_BAUD_45450 = 2
    PB_PHY_BAUD_93750 = 3
    PB_PHY_BAUD_187500 = 4
    PB_PHY_BAUD_500000 = 5
    PB_PHY_BAUD_1500000 = 6
    PB_PHY_BAUD_3000000 = 7
    PB_PHY_BAUD_6000000 = 8
    PB_PHY_BAUD_12000000 = 9

    # RTS mode
    PB_PHY_RTS_ALWAYS_LO = 0
    PB_PHY_RTS_ALWAYS_HI = 1
    PB_PHY_RTS_SENDING_HI = 2
    PB_PHY_RTS_SENDING_LO = 3

    # GPIO numbers (BCM)
    GPIO_RESET = 17
    GPIO_IRQ = 27
    GPIO_SS = 8
    GPIO_MISO = 9
    GPIO_MOSI = 10
    GPIO_SCK = 11

    baud2id = {
        9600: PB_PHY_BAUD_9600,
        19200: PB_PHY_BAUD_19200,
        45450: PB_PHY_BAUD_45450,
        93750: PB_PHY_BAUD_93750,
        187500: PB_PHY_BAUD_187500,
        500000: PB_PHY_BAUD_500000,
        1500000: PB_PHY_BAUD_1500000,
        3000000: PB_PHY_BAUD_3000000,
        6000000: PB_PHY_BAUD_6000000,
        12000000: PB_PHY_BAUD_12000000,
    }

    def __init__(self, device=0, chipselect=0, debug=False):
        self.device = device
        self.chipselect = chipselect
        self.debug = debug

        try:
            try:
                # Initialize GPIOs
                GPIO.setmode(GPIO.BCM)  # Use Broadcom numbers
                GPIO.setwarnings(False)
                GPIO.setup(self.GPIO_RESET, GPIO.OUT, initial=GPIO.LOW)
                GPIO.setup(self.GPIO_IRQ, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
                GPIO.add_event_detect(self.GPIO_IRQ, GPIO.RISING)
                time.sleep(0.05)
            except RuntimeError as e:
                raise PhyError("Failed to initialize GPIOs: %s" %\
                 str(e))

            # Initialize SPI
            try:
                self.spi = SpiDev()
                self.spi.open(device, chipselect)
            except IOError as e:
                raise PhyError("Failed to open SPI device %d.%d: %s" %\
                 (device, chipselect, str(e)))
            try:
                self.spi.mode = 0
                self.spi.bits_per_word = 8
                self.spi.cshigh = False
                self.spi.lsbfirst = False
                self.spi.max_speed_hz = 200000
            except IOError as e:
                try:
                    self.spi.close()
                    self.spi = None
                except:
                    pass
                raise PhyError("Failed to configure SPI device %d.%d: %s" %\
                 (device, chipselect, str(e)))

            # Get the controller out of hardware reset
            GPIO.output(self.GPIO_RESET, GPIO.HIGH)
            time.sleep(0.2)

            # Send a software reset
            self.sendReset()
            # Upload default config
            self.profibusSetPhyConfig()
        except:
            GPIO.cleanup()
            raise

    def cleanup(self):
        self.spi.close()
        self.spi = None
        GPIO.cleanup()

    # Poll for received packet.
    # timeout => In seconds. 0 = none, Negative = unlimited.
    def poll(self, timeout=0):
        limit = TimeLimited(timeout)
        while GPIO.event_detected(self.GPIO_IRQ):
            if limit.exceed():
                return None
            limit.sleep(0.001)
        limit.add(0.5)
        while not limit.exceed():
            fc = self.spi.readbytes(1)[0]
            if fc != CpPhyMessage.RPI_PACK_NOP:
                break
        else:
            return None
        reply = [fc]
        reply.extend(self.spi.readbytes(CpPhyMessage.RASPI_PACK_HDR_LEN - 1))
        payloadLen = reply[1] & 0xFF
        if payloadLen:
            reply.extend(self.spi.readbytes(payloadLen))
        message = CpPhyMessage(0)
        message.setRawData(reply)
        if self.debug:
            print("[PHY] recv msg:", message)
        return message

    def __sendMessage(self, message):
        if self.debug:
            print("[PHY] send msg:", message)
        self.spi.writebytes(message.getRawData())

    def sendReset(self):
        self.__sendMessage(CpPhyMessage(CpPhyMessage.RPI_PACK_RESET))
        reply = self.poll(timeout=-1)
        if reply.fc != CpPhyMessage.RPI_PACK_ACK:
            raise PhyError("Failed to reset PHY")

    def profibusSetPhyConfig(self,
                             baudrate=19200,
                             rxTimeoutMs=100,
                             bitErrorChecks=True,
                             rtsMode=PB_PHY_RTS_SENDING_HI):
        try:
            baudID = self.baud2id[baudrate]
        except KeyError:
            raise PhyError("Invalid baud-rate")
        if rxTimeoutMs < 1 or rxTimeoutMs > 255:
            raise PhyError("Invalid RX timeout")
        payload = [
            baudID, rxTimeoutMs, 1 if bitErrorChecks else 0, rtsMode & 0xFF
        ]
        message = CpPhyMessage(CpPhyMessage.RPI_PACK_SETCFG, payload)
        self.__sendMessage(message)
        reply = self.poll(timeout=-1)
        if reply.fc != CpPhyMessage.RPI_PACK_ACK:
            raise PhyError("Failed to upload config")

    def profibusSend_SDN(self, telegramData):
        self.__sendMessage(
            CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SDN, telegramData))

    def profibusSend_SRD(self, telegramData):
        self.__sendMessage(
            CpPhyMessage(CpPhyMessage.RPI_PACK_PB_SRD, telegramData))
예제 #6
0
class SPIimplementation(SPI):
    """SPI imlementation wrapping spidev library. Extends :class:`SPI`.
    
    Args:
        port (int): SPI port on raspberry pi.
        devive (int): SPI device of raspberry.

    Raises:
        ImportError: If spidev is not installed.
    """
    def __init__(self, port, device):
        self._port = port
        self._device = device
        self._interface = None
        if SpiDev is None:
            raise ImportError('failed to import spidev')
        self._interface = SpiDev()
        self._interface.open(port, device)
        self._interface.max_speed_hz = 1000000

    def read(self, n):
        """Read n words from spi
        
        Args:
            n (int): The number of bytes to read from spi.
        """
        return self._interface.readbytes(n)

    # TODO: Check writebytes2 for large lists
    def write(self, data):
        """Write data to spi
        
        Args:
            data (list): A list with integers to be writter to the device.
        """

        self._interface.writebytes2(data)

    def read_write(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._interface.xfer2(data)

    def close(self):
        if self._interface is not None:
            self._interface.close()
        self._interface = None

    def _get_clock_mode(self):
        return self._interface.mode

    def _set_clock_mode(self, value):
        self._interface.mode = value

    def _get_lsb_first(self):
        return self._interface.lsbfirst

    def _set_lsb_first(self, value):
        self._interface.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._interface.cshigh

    def _set_select_high(self, value):
        self._interface.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._interface.bits_per_word

    def _set_bits_per_word(self, value):
        self._interface.bits_per_word = value
class SPI(object):
    """
    classdocs
    """
    __LOCK_TIMEOUT = 10.0

    # ----------------------------------------------------------------------------------------------------------------

    def __init__(self, bus, device, mode, max_speed):
        """
        Constructor
        """

        self.__bus = bus
        self.__device = device
        self.__mode = mode
        self.__max_speed = max_speed

        self.__connection = None

    # ----------------------------------------------------------------------------------------------------------------

    def open(self):
        if self.__connection:
            return

        self.acquire_lock()

        self.__connection = SpiDev()
        self.__connection.open(self.__bus, self.__device)

        self.__connection.mode = self.__mode
        self.__connection.max_speed_hz = self.__max_speed

    def close(self):
        if self.__connection is None:
            return

        self.__connection.close()
        self.__connection = None

        self.release_lock()

    # ----------------------------------------------------------------------------------------------------------------

    def acquire_lock(self):
        Lock.acquire(self.__lock_name, SPI.__LOCK_TIMEOUT)

    def release_lock(self):
        Lock.release(self.__lock_name)

    @property
    def __lock_name(self):
        return "%s-%s" % (self.__class__.__name__, self.__bus)

    # ----------------------------------------------------------------------------------------------------------------

    def xfer(self, args):
        return self.__connection.xfer(args)

    def read_bytes(self, count):
        return self.__connection.readbytes(count)

    # ----------------------------------------------------------------------------------------------------------------

    @property
    def bus(self):
        return self.__bus

    @property
    def device(self):
        return self.__device

    # ----------------------------------------------------------------------------------------------------------------

    def __str__(self, *args, **kwargs):
        return "SPI:{bus:%d, device:%s, mode:%d, max_speed:%d, connection:%s}" % \
               (self.__bus, self.__device, self.__mode, self.__max_speed, self.__connection)