RS232 data transfers OK with Hyperterminal, but not with PySerial

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dave067
    New Member
    • Sep 2010
    • 17

    RS232 data transfers OK with Hyperterminal, but not with PySerial

    Hi

    I'm a Python newbie trying to write a datalogger to acquire data from a laboratory meter using RS232.

    Hardware: Samsung N100 laptop. Maplin's USB-Serial converter dongle. TSI 4100 series laboratory flow meter

    Software: Windows XP. Python 2.5 & IDLE interface. HDD Free Serial Port Monitor 3.31. Hyperterminal Private Edition v5.0 (Drivers for USB dongle installed, Windows firewall exception made for COM1).

    RS232 Port Settings: Baud rate:38400, data bits:8, Parity:None, Stop bits:1, Flow control: None

    The meter requires me to send a command code before it returns data to me (both in ASCII format). In its simplest form, sending the test command "?<CR>" (= 0x3F
    0x0D) should return the message "OK<CR>" (= 0x4F 0x4B 0x0D).

    This works fine via Hyperterminal. The USB adaptor is correctly identified as 'COM1', and I can verify that the correct data is sent or received by:
    1) Seeing a "data transfer" indicator flash on the meter
    2) Seeing the ASCII & HEX codes for the sent and received data displayed the serial port monitor software
    3) Using an oscilloscope on the serial port leads and analysing the pulses.

    However when I try to do the same in Python using the following code, the code executes fine and indicates that COM1 has been used, but no actual data transfer
    occurs: the monitor's indicator doesn't flash, and although the serial port monitor registers that the connection has been opened and then closed by Python,
    no data is sent or received.

    I've checked the documentation and examples on the pySerial website and relevant postings on the forum, but I'm stuck. I'm sure I must have made a dumb mistake somewhere in my code, but can't find it, and would be very grateful for your help. Also as a Python newbie, any general hints on how to write my code neater and more compactly would be appreciated.
    Many thanks in anticipation

    Dave


    Python output is:

    >>>
    Enter name: dave
    Hi dave, opening port
    COM1
    []
    done!
    >>>

    Code follows:

    Code:
    import serial
    se = serial.Serial()
    se.baudrate = 38400
    se.bytesize = 8
    se.stopbits = 1
    se.xonxoff = 0
    se.rtscts = 0
    se.timeout = 0
    se.port = 0     # = COM1
    parity=serial.PARITY_NONE
    
    x = raw_input("Enter name: ")
    print "Hi " + x +", opening port"
    se.open()               #open port
    
    print se.portstr       # confirm which port was really used
    se.write = "?\r"    # send command string to meter 
    
    data = se.readline()    # read data from meter 
    data = data.split()
    print data
    
    se.close()             # close port
    print "done!"
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    You never sent the command. The write method call requires parentheses and an argument. Try this:
    Code:
    se.write("?\r")

    Comment

    • Dave067
      New Member
      • Sep 2010
      • 17

      #3
      Many thanks!!
      Now the parentheses are in place, the data is sent to the monitor fine...
      In order to receive the reply from the monitor, I had to increase the se.timeout parameter to 4 to allow time for the monitor to respond and send a return signal. Not sure whether this is the proper way to do things, but it seem to work.

      Is there a neater way of writing all of the port initiallisation parameters, so they're all in a set of parentheses; or is it OK to write them in a long list like I've done?

      Thanks again

      Kind regards

      Dave

      Comment

      • Dave067
        New Member
        • Sep 2010
        • 17

        #4
        .. also, when I was accessing the meter via Hyperterminal, the ASCII command string "DCFTP0001" <CR> would instruct the meter to send back an 18 byte string of characters corresponding to the flow rates that I am trying to log. This worked fine.

        However...
        When I replace the ASCII sequence to check communication in my Pythonscript:
        se.write("?\r")
        ...with the command to request data:
        se.write("DCFTP 0001\r")

        ..the sequence is sent in the Serial Port Monitor, but the data indicator light on the meter doesn't flash, no data is returned, and bizarrely, the output from Python is the same as for the test sequence:
        "OK"

        Is there some sort of buffer that I have to clear with a Python command between successive "read" and "write" commands to the port?

        Thanks again

        Dave

        Comment

        • bvdet
          Recognized Expert Specialist
          • Oct 2006
          • 2851

          #5
          If your code works for you, then you have well written code. :)
          Seriously, the way you set the parameters is fine (except for the parity assignment), but you could have set the parameters when you instantiated serial.Serial() , which is what I prefer to do. Example:
          Code:
          se = serial.Serial(port=0,
                             baudrate=38400,
                             bytesize=serial.EIGHTBITS,
                             parity=serial.PARITY_NONE,
                             stopbits=serial.STOPBITS_ONE,
                             timeout=4,
                             xonxoff=False,
                             rtscts=False,
                             writeTimeout=None,
                             dsrdtr=False,
                             interCharTimeout=None)
          When using keywords as shown above, it makes the code quite readable.

          Your next step may be to create a GUI interface. Tkinter, wxPython, and several other GUI toolkits are well suited to applications such as yours.

          The pySerial API documentation can be found here.

          Comment

          • bvdet
            Recognized Expert Specialist
            • Oct 2006
            • 2851

            #6
            Honestly, I've never used pySerial. Would you post the code you used to send the command? You could try setting a write timeout.

            Comment

            • Dave067
              New Member
              • Sep 2010
              • 17

              #7
              Hi
              Thanks for the advice & links to the documentation.
              Ports open and close the in serial monitor, but no data transferred in either direction, and PySerial seems to be unable to access COM1 any more - not sure why.

              Have tried rebooting the laptop, disconnecting/re-inserting USB dongle & flow meter. No joy :-(
              Any suggestions welcome!
              Thanks
              Dave

              PySerial output:
              >>>
              Enter name: dave
              Hi dave, opening port

              Traceback (most recent call last):
              File "C:\Python25\se rial_hello world.py", line 18, in <module>
              se.open() #open port
              File "C:\Python25\Li b\site-packages\serial \serialwin32.py ", line 56, in open
              raise SerialException ("could not open port %s: %s" % (self.portstr, ctypes.WinError ()))
              SerialException : could not open port COM1: [Error 13] Access is denied.
              >>>

              Code:
              import serial
              se = serial.Serial(port=0,
                                  baudrate=38400,
                                  bytesize=serial.EIGHTBITS,
                                  parity=serial.PARITY_NONE,
                                  stopbits=serial.STOPBITS_ONE,
                                  timeout=4,
                                  xonxoff=False,
                                  rtscts=False,
                                  writeTimeout=1,
                                  dsrdtr=False,
                                  interCharTimeout=None)
              
              x = raw_input("Enter name: ")
              print "Hi " + x +", opening port"
              
              se.open()               #open port
              print se.portstr       # confirm which port was really used
              se.write("DCFTP0001\r")     # send command string to meter requesting 1 sample (0001) for Flow(F), Temp(T) and Pressure (P)
              
              data = se.readline()    # read data from meter 
              #data = data.split()
              print data
              
              se.close()             # close port
              print "done!"

              Comment

              • bvdet
                Recognized Expert Specialist
                • Oct 2006
                • 2851

                #8
                Try closing the port before opening it.

                Comment

                • Dave067
                  New Member
                  • Sep 2010
                  • 17

                  #9
                  Hi again
                  I think the problem was a conflict on accessing COM1 due to a combination of both Hyperterminal & Windows Automatic Updates running in the background, and also the Serial Port Monitor being opened in the wrong sequence, before the USB dongle was connected. D'Oh!
                  Am now up and running again :-)
                  If I get the rest of the code written, I'll post it to the group in case it is of help to anyone working on a similar project.
                  Thanks again for your help
                  Dave

                  Comment

                  • bvdet
                    Recognized Expert Specialist
                    • Oct 2006
                    • 2851

                    #10
                    Thanks for the feedback Dave. Nice thread!

                    Comment

                    • Nawar0066
                      New Member
                      • Jul 2021
                      • 1

                      #11
                      Hallo Dave,

                      could you help me please if you got the code because i have the same problem with same device

                      Comment

                      Working...