eceforge
eceforge

Reputation: 1

Python Serial readline doesn't work when called from within Object

So I'm writing a simple serial driver for an agilent power supply with pyserial. Everything works fine until I package it up as a class and try to run some simple serial write/read from within the object that I create.

A code snippet of the class:

class agilent:
    """
    Class for controlling the chroma class power supplies
    Basically a wrapper around the serial interface to the chromas
    """

    def __init__(self, port_name="/dev/ttyUSB0", baud_rate=9600):
        self.ser = serial.Serial(port=port_name, baudrate=9600, bytesize=8, parity=serial.PARITY_NONE, stopbits=2, dsrdtr=1, timeout=5)
        self.reset()
        self.identify() #Calls the IDN function to see if this is a multi-service device
        print("Connected to: " + self.idn)
        if self.multi_service:
            print("This is a multi-service device, please make sure to specify one of: P25V, P25N, or P6V when setting limits")

    def reset(self):
        """
        Reset the agilent power supply to a reasonable(safe) settings
        """
        self.ser.write("*CLS\n")  # Clear any errors on the chroma
        self.ser.write("system:remote\n")  # set the controls back to remote

    def identify(self):
        self.ser.write('*IDN?\n')
        self.idn = self.ser.readline()
        if 'E3631' in self.idn:
            self.multi_service=True
        else:
            self.multi_service=False

        return self.idn

When I call the identify() function from the __init__() function the readline() times out and returns an empty string.

When running in ipython and import the class and create an object, I can call the identify function manually on the object and it works just fine....so either I'm doing something wrong with class methods or some funny business is going on with the serial class. I know the right function is being called with the right context because if I put a

print(self.ser.port)

in the identify function it returns the right instance information.

Any ideas?

A typical run looks likes this:

from agilent_ps_controller import agilent
remote_ps = agilent() # << This hangs until the readline in __init__() times-out
remote_ps.reset()  # Serial message is correctly written on wire
remote_ps.identify() # << this works just fine! Why didn't it work when the object constructor calls it?
remote_ps.__init__() # << this also times-out the readline.

Upvotes: 0

Views: 1296

Answers (1)

Jonathan
Jonathan

Reputation: 11

I had the same problem exactly. It turns out that pyserial's readline() uses \n as the default eol character. If your device uses something else, such as \r\n as eol (as Arduino's println() does, for instance), this might be the problem.

So, to make a long story short, try calling readline() this way:

self.ser.readline(eol=b'\r\n')

or any other eol character(s) your device uses.

Upvotes: 1

Related Questions