Establishing communication with device through RS232 using PySerial or PyVisa - python

Trying to communicate with a McPherson 747 Device Controller for the Filter Wheel on a lab instrument. It is connected to the lab computer through RS232 to usb. I've connected and communicated with other devices through serial before.
It seems that for a read request, I need to send an enquiry and header and then the Device will acknowledge and send data.
The manual for the Device says that all data is exchanged in ASCII format. Though there are also a few tables in the manual that has inputs in Hex ASCII code. The manual says that a three-byte enquiry is Hex 4E2105 or text N!< ENQ >. Acknowledge is Hex 4E2106 or text N!< ACK > . The header is a mix of several Hex ASCII inputs for reading and writing based on what information the user wants.
The issue I am having is when I code the serial information and send the enquire input, it always sends an error due to communication with the device. I am unfamiliar with Hex. Do I need to be sending the entire enquire, headeras one input, or can I send them separately? I can also try to set up communication with PyVisa but I've gotten similar errors.
Through serial:
import codecs
import serial
try:
ser = serial.Serial(port='COM1',
baudrate = 9600,
timeout = None,
xonxoff = False,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE,
bytesize = serial.EIGHTBITS,
)
ser.close()
string = '4E2105'
enquire = codecs.decode(string,'hex')
ser.open()
ser.write(enquire); #ascii intput for pressing enter on keyboard
ser.read_until(size=None) #reads out feedback until no data is left
ser.close()
msg = f"Program communication initialized"
print(msg)
except Exception as ex:
msg = f"Error: {ex}"
print(msg)
Error: could not open port 'COM1': FileNotFoundError(2, 'The system cannot find the file specified.', None, 2)
Through Pyvisa:
import pyvisa
import serial
import codecs
string = '4E2105'
enquire = codecs.decode(string,'hex')
rm = pyvisa.ResourceManager()
rm.list_resources()
# ('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::12::INSTR')
inst = rm.open_resource('asrl1::instr')
inst.write_termination='\r'
inst.read_termination='\r'
inst.baud_rate = 9600
inst.data_bits = 8
inst.parity = visa.constants.Parity.none
inst.flow_control = visa.constants.VI_ASRL_FLOW_NONE
inst.write(enquire)
print(inst.query("N!<ENQ>"))
rm.close()
VisaIOError: VI_ERROR_RSRC_NFOUND (-1073807343): Insufficient location information or the requested device or resource is not present in the system.

Related

Python, Data Received from RS232 COM1 port is returning b'\x05' and b'\x04'

I am doing an instrument integration where the instrument name is Horiba ES60. I am using an RS232 port for communicating for PC and instrument.
I have tested the PC and instrument connection through the Advance Serial Port logger and am getting the monitor result.
I have confirmed that the instrument setting and my script setting are the same.
I have written a simple script in python to read the port data. below is the script.
import time
import serial
sSerialPort = serial.Serial(port = "COM1", baudrate=9600,
bytesize=8, timeout=1, stopbits=serial.STOPBITS_ONE)
sSerialString = "" # Used to hold data coming over UART
print("Connected to : ",sSerialPort.name)
while(True):
# Wait until there is data waiting in the serial buffer
if(sSerialPort.in_waiting > 0):
# Read data out of the buffer until a carraige return / new line is found
sSerialString = sSerialPort.readline()
# Print the contents of the serial data
print(sSerialString)
Output:
b'\x05'
b'\x04'
The expected output is different and I am getting the above one.
Can someone please help to understand what's going wrong?
how to deal with port data in python.

RS485 communication with Python

Here's my problem:
I need to send Hexadecimal commands to a device via RS485 to make it work.
I can communicate perfectly with this device using RealTerm, I send my requests and I receive consistent responses.
However now I would like to send them with a python script and I don't know what I'm doing wrong but I don't get any response from the device when I try to send commands to it with my script.
Here is the script :
import serial # import the module
ComPort = serial.Serial('COM3') # open COM3
ComPort.baudrate = 9600 # set Baud rate to 9600
ComPort.bytesize = 8 # Number of data bits = 8
ComPort.parity = 'N' # No parity
ComPort.stopbits = 1 # Number of Stop bits = 1
data = bytearray(b'\xfa\x02\x02\x2a\xfe\x0c')
No = ComPort.write(data)
print(data) # print the data
dataIn = ComPort.readline() # Wait and read data
print(dataIn) # print the received data
ComPort.close() # Close the Com port
I founded the solution to my problem,
it was just my reading that wasn't getting through, I used .read(6) and it works now.

Error during the reading of the serial port in VB

I set up a bluetooth connection between Raspberry and a computer. I wish to carry out a pilot icon which would allow me to check if connection is always present. For that I carried out a Thread. For the test, I sending a message on the link of the PC towards RPi, if the Rpi receive something , she reference me a message and if I receive it on my computer is that the connection is always present. The probelm is that I have an error at the time of the reception side PC.
Here the detail: The operation of E/S was abort because of the stop of a thread or the request of an application.
Here two codes for the connection series:
Pc side with VB :
Private Sub checkBT()
Dim buffer As String = ""
While True
BluetoothPort.Write("Test")
buffer = BluetoothPort.ReadLine()
While buffer = ""
buffer = BluetoothPort.ReadLine()
End While
WriteInLog("" & buffer)
checkBT_thread.Sleep(20000)
End While
End Sub
Rpi side with Python:
import serial
serial_com = serial.Serial("/dev/rfcomm0", baudrate = 115200, timeout = 0, writeTimeout = 5)
print "INIT Bluetooth connection"
while 1:
x = serial_com.readline()
if x == "Test":
print x
serial_com.write("Recu")
Do you have an idea about the problem please?
Can the error come owing to the fact that I use of Windows forms?
I solved my problem with the serialPort.ReadExisting() method.

serial communication with USB device using 'GNET' protocol

I have a USB device with the following specification. Page 22 describes the GNET protocol that should be used to interact with the device.
The connection is fine but the device just doesn't give me any response, so I think I am not sending the correct data to it, maybe missing the handshake?
From Specification
Support TTY (TELE TYPE) OPERATION - Use TTY to send commands and messages
Use ASCII value for each field and use Separator "," between two
Fields.
connect_and_send.py
import serial
port = "COM3"
baud = 9600
ser = serial.Serial(port, baud, timeout=1)
if ser.isOpen():
print(ser.name + ' is open...')
# STX, N, CR
to_send = b'\x02\x4e\x0d'
print "Sending {}".format(to_send)
ser.write(to_send)
out = ser.read()
print('Receiving...'+out)
COM3 is the correct port:
Any help and guidance would be greatly appreciated.
You havenever​ to use \x4e, this is the Negative Acknowledge from the device.
Try
to_send = b'\x02F\x0d'
to get Firmware Version
I contacted the supplier in the end and the issue was setting to wrong baud rate. Changing from 9600 to 19200 resolved the problem.

get device name connected to port /dev/ttyACM0

Is there a way to get the device name connected to the serial port?
This code gives me just the name of the serial port. But I need the device name connected to it i.e. Nokia Phone
import serial
import time
ser = serial.Serial('/dev/ttyACM0',
460800,
timeout=5,
xonxoff = False,
rtscts = False,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE)
sere = ser.name
print (ser, sere)
I've been checking other possibilities like gammu-detect but I would like to have a self standing python script that does this operation. Is there a way to get it done with pyserial?
Yes, of course.
But this is not strictly linked to serial port itself. It depends on the protocol the device is using.
In essential, you send some preset initial data to the device and it responds with manufacturer, name, model and version or some combination of these.
I am not sure whether this is standardized or not, you will have to search for it.
If it is standardized, it is most probably something like:
1. Open the port with 9600 baud rate
2. Send the request for info
3. Use info to reset the port etc.
I know that some programs do this. You can even hear old 56K modems reacting to the query when detection algorithm asks them who they are.
Now, you have to search whether this is a standard procedure or each device has its own.
If you are searching for phones, then very probably there is one for phone versions, perhaps each per OS like iOS, Symbian, Android, Windows *, ...
If you cannot find the protocol on the internet, then install virtual card for serial ports, perform man in the middle on looped ports to see what data is sent at initial communication with the phone application.
Note: Don't watch for data when connecting to the internet i.e. using the phone as a modem. You will see only AT&T protocol, which wouldn't help you much.
If you want to see how it works universally, use same technique with virtual serial card but when new device wizard detects for new hardware.
P.S. I found something!
Try sending:
"\x02S\x00\x00\x00\x00\x03"
You should get back some data containing numeric identifier of a device. Like serial number.
Now things work well! I had to type the .read command. Here the solution:
import serial
import time
ser = serial.Serial('/dev/ttyACM0',
460800,
timeout=5,
xonxoff = False,
rtscts = False,
bytesize = serial.EIGHTBITS,
parity = serial.PARITY_NONE,
stopbits = serial.STOPBITS_ONE)
#s = input('Enter AT command --> ')
#print ('AT command = ' + s)
ser.write(bytes('AT+CGMI' + '\r\n'))
ser.timeout = 1
response = ser.read(999)
print(response)
ser.close()

Categories