5
\$\begingroup\$

I asked this question on the Engineering StackExchange and someone said it might be more appropriate here.


I want to interface an old Shimadzu spectrophotometer (Model UV-1601, manual here) through its RS-232C port, which is described in the manual in Fig. 12.2:

RS-232C cable for UV-1601 (IBM)

I want to use a USB Type C connection on my laptop, so I bought this adapter from StarTech, with the following pinout diagram:

RS-232 DB9 male pinout

Next, I used PySerial to try and communicate with the instrument. That's when things started to become difficult for me. The manual of the spectrophotometer gives the details of the serial transmission parameters:

Transmission parameters

The manual also describes an example protocol (although the code is in BASIC) to change the instrument wavelength:

Protocol

In this protocol:

  • ENQ is 05 in hexadecimal
  • ACK is 06 in hexadecimal
  • EOT is 04 in hexadecimal
  • NUL is 00 in hexadecimal
  • w, 6, and 0 are interpreted as ascii caracters (for example 'w' is 77 in hexadecimal

In Python, I have a short program that opens the serial communications:

import serial
device = serial.Serial(port='COM4', baudrate=9600, bytesize=serial.SEVENBITS, parity=serial.PARITY_ODD, stopbits=serial.STOPBITS_ONE, timeout=.1)

Then, I use this line to send the ENQ signal:

device.write(b'\x05')

Now here comes the trouble. If I try to read the ACK byte with:

device.read()

It returns an empty byte:

b''

If I try to send the rest of the command it won't work. If I send the ENQ, and straight after send the command:

device.write(b'\x77\x36\x30\x30\x30\x00')

I hear the device moving the slit to the new position, but the screen of the instrument isn't updated until I send an ACK signal. Also, I cannot send another command until I send that same ACK signal.

My main problem is that I can't output the instrument data.

I want to focus on this small example to make sure everything is right first.

The BASIC program described in the manual is as follows:

100 'UV-1601 PC Control Program
110 DIMBUF$(32)
120 ENQ $ =CHR $ (&H5) : EOT $ =CHR $ (&H4) : ESC $ =CHR $ (&H1B)
130 NUL $ =CHR $ (&H0) : ACK $ =CHR $ (&H6) : NAK $ =CHR $ (&H15)
140 '
150 ' GO TO A
160 OPEN "COM1: 071NN" AS#1
170 FOR 1=0 TO 99: NEXT
180 PRINT #1,ENQ $;
190 IF INPUT $ (1,#1)< >ACK $ THEN 170
200 FOR 1=0 TO 99: NEXT
210 PRINT #l,"w6000" +NUL$;
220 IF INPUT $ (1, #1)< >ACK $ THEN BEEP : PRINT #1, ESC $;: GOTO 250
230 IF INPUTS (1, #1)< >EOT$ THEN BEEP: PRINT#1, ESC $;: GOTO 250
240 PRINT #1, ACK $; -o
250 CLOSE #1 O
260 END 

Does anyone know why I can't seem to read the bytes from the instrument? Is it because of my RS-232C to USB C adapter, or is it related to PySerial?

EDIT: this is the cable I ended up making (this is the same wiring as suggested by @jonathanjo but with a female connector on the left-hand side to the USB adaptor and male connector on the right-hand side to the instrument)

enter image description here

With this cable, I could read the data from the spectro, but oddly enough, changing the wavelength still doesn't work as expected, but I guess I will live with that problem.

For those interested, this is a repository where I store my Python code for this instrument.

Thank you all :)

\$\endgroup\$
6
  • 2
    \$\begingroup\$ So what is the question? Just because it is an electronic device, it does not mean writing a Python program to communicate with it has anything to do with electronics, it's just usage of an electrical device and thus off-topic. Likely just how the device responds and when, so pyserial timing with the device is important. \$\endgroup\$
    – Justme
    Apr 24, 2023 at 14:02
  • 2
    \$\begingroup\$ OK, so have you made sure the pin 7 on device is ground, and have you built a custom cable that matches the pinout? \$\endgroup\$
    – Justme
    Apr 24, 2023 at 14:42
  • 1
    \$\begingroup\$ @jonathanjo The handshake links are irrelevant if you are making the PC program and choose to not use handshaking pins so you don't have to fake them. \$\endgroup\$
    – Justme
    Apr 24, 2023 at 15:05
  • \$\begingroup\$ @Justme pin 7 is not GND on a DB9 connector; pin 5 is GND. \$\endgroup\$
    – Andy aka
    Apr 24, 2023 at 15:06
  • \$\begingroup\$ @justme -- my mistake, I read the diagram wrongly, deleted my comments. \$\endgroup\$
    – jonathanjo
    Apr 24, 2023 at 15:18

1 Answer 1

5
\$\begingroup\$

Note that your device has non-standard wiring, as pointed out in comments, and in particular the signal ground. You'll have to ensure you have the three wires connected between your device and your PC as shown. The connections inside the PC connector (DTR to DSR and CTS to DTS) are optional and ideally should omitted if you ensure your program doesn't require them.)

At least one problem, the empty bstring, is caused by the timeout in your open call:

import serial
device = serial.Serial(port='COM4',
    baudrate=9600,
    bytesize=serial.SEVENBITS,
    parity=serial.PARITY_ODD,
    stopbits=serial.STOPBITS_ONE,
    timeout=.1)

The 0.1 second timeout is evidently shorter than needed, and so read returns an empty string. You could just try making it longer, or putting a loop around.

From the manual for the serial module:

read(size=1)

  • Parameters: size – Number of bytes to read.
  • Returns: Bytes read from the port.
  • Return type: bytes

Read size bytes from the serial port. If a timeout is set it may return less characters as requested. With no timeout it will block until the requested number of bytes is read.

You'll need to have some kind of polling or much longer timeouts in order to get your data. You might find, with a slow-responding mechanical machine, that you can just put appropriate delays in various places.

You might also have some need of flush to ensure the bytes are sent.


Edit: The following is the minimal cabling requirement as I understand it, and you need to make a little adaptor from two D-type 9-way sockets.

enter image description here

\$\endgroup\$
8
  • \$\begingroup\$ Thank you for your answer. I will try the timeout asap. However, regarding the wiring. I think I misunderstood something. Are DTR, GND, and DSR all connected together? Or is it DTR and DSR together only (and the wire goes over the GND wire)? \$\endgroup\$
    – Omnistic
    Apr 25, 2023 at 10:47
  • \$\begingroup\$ @Omnistic I'll draw what I think is correct. \$\endgroup\$
    – jonathanjo
    Apr 25, 2023 at 11:05
  • \$\begingroup\$ @Omnistic "Are DTR, GND, and DSR all connected together?" No "Or is it DTR and DSR together only (and the wire goes over the GND wire)" YES. \$\endgroup\$
    – jonathanjo
    Apr 25, 2023 at 11:49
  • \$\begingroup\$ jonathanjo one more question, when you say "omit" you mean I don't need to do this connection? Or is "omit" referring to a connection onto the same connector? \$\endgroup\$
    – Omnistic
    Apr 25, 2023 at 20:41
  • \$\begingroup\$ "omit"="do not connect". You only need three wires, drawn red, green, grey. \$\endgroup\$
    – jonathanjo
    Apr 25, 2023 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.