Trying to connect Cobright DX4 laser to computer using Pyvisa - python

I am trying to connect a Cobright DX4 laser to my computer to control it from my computer. However I am unable to do so. I have tried using both rm.openresource() and through pyserial. However neither seem to work.
#import visa
import serial
import numpy as np
#rm = visa.ResourceManager() #checks devices that are
rm = visa.ResourceManager('#py') #to take the python backend
#rm = visa.ResourceManager('#sim')
print(rm.list_resources())
inst1 = rm.list_resources()
The output is ('ASRL5::INSTR')
However when I query the ID:
inst2 = rm.open_resource("ASRL5::INSTR",read_termination = '\n', write_termination="\r\n")
print(inst2.query("*IDN?"))
I get a timeout error
"VisaIOError: VI_ERROR_TMO (-1073807339): Timeout expired before operation completed."
I have also tried to connect using pyserial.
import pyvisa as visa # note the recommended way to import pyvisa changed as there is an unrelated visa module
#import visa
import serial
import numpy as np
import serial.tools.list_ports
import sys
list = serial.tools.list_ports.comports()
connected = []
for element in list:
connected.append(element.device)
print("Connected COM ports: " + str(connected))
# compliments of https://stackoverflow.com/questions/12090503/listing-available-com-ports-with-python#14224477
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
# !attention assumes pyserial 3.x
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
print("Availible COM Ports: " + str(result))
Connected COM ports: ['COM5']
Availible COM Ports: ['COM5']
ser = serial.Serial(
port="COM5", # assumes pyserial 3.x, for 2.x use integer values
baudrate=9600,
bytesize=8,
parity="E", # options are: {N,E,O,S,M}
stopbits=1,
timeout=1)
print(ser)
Serial<id=0x243e051beb0, open=True>(port='COM5', baudrate=9600, bytesize=8, parity='E', stopbits=1, timeout=1, xonxoff=False, rtscts=False, dsrdtr=False)
ser.isOpen()
True
Now when I try to send a command eg
ser.write(str.encode('*IDN?'))
5
is the output. I am unsure as to what the issue. I cannot decode having encoded.
Any help appreciated, and sorry for the long post! I have also connected a power meter which worked fine.

Related

Recognition of a specific USB device in python

I am making app in python, that connects with Arduino. I want this app to work on different computers, when arduino is connected to any port. I was trying to do a function that checks to which port is arduino connected to:
def arduinoConnect():
t=0
temp = 0;
while 1:
i = str(t)
try:
temp = serial.Serial('com'+i, 9600)
if temp:
print("COM" + i + " Connected")
break
except:
print("COM" + i + " Empty")
t = t + 1
if t == 41:
break
return temp
But this code only sees if anything is connected, so when i am also using some bluetooth devices, or other microcontrolers, it takes the device that is connected to the com port with the lowest number.
Next idea was to take PID and VID number:
import serial
import serial.tools.list_ports
for port in serial.tools.list_ports.comports():
print(port.hwid)
But i have one more device connected to COM Port, that gives exactly the same numbers, only different location:
USB VID:PID=1A86:7523 SER= LOCATION=1-4
USB VID:PID=1A86:7523 SER= LOCATION=1-5
I also tried to get a specific id of a connected USB device:
import serial
def serial_ports():
ports = ['COM%s' % (i + 1) for i in range(256)]
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
print(s)
except (OSError, serial.SerialException):
pass
return result
if __name__ == '__main__':
print(serial_ports())
And it returns the ID of a device, which is unique to every device, but changes every time i disconnect and connect again the device.
My question is how to let my code recognize and connect one and only device I want? On any computer, connected to any port.
I understand your problem as such that you wish to have python code that can connect to an arduino device which is connected to any port, on any computer.
So the solution is to uniquely identify the arduino device even when other devices are plugged in.
It should work when you get the device serial number:
import serial
import serial.tools.list_ports
def get_arduino_serial_number():
for port in serial.tools.list_ports.comports():
if 'Arduino' in port.description:
return port.serial_number
return None
whether this works or not is dependent on port.description.
Change USB COM port description
Get ports by description
With the serial number of the Arduino device, you can then connect to it using:
ser = serial.Serial(port='COMx', baudrate=9600, timeout=1,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
Opening serial ports | pySerial

Setting a default "SERIAL PORT" for a serial port device in "LINUX"

I am Using a Python to access a serial port from ubuntu 20.4. I send and read data from the Connected serial port.
The code looks like :
import time
import serial
ser=serial.Serial("/dev/ttyACM0",115200)
ser.write(b'\xFA\x0B\x1B\x00\x00\x00\x00\x00\x00\xFB')
while True:
try:
#ser.write(command)
s2=ser.read(10).hex()
print(s2)
except KeyboardInterrupt:
ser.flushInput()
ser.flushOutput()
ser.close()
break
The issue is, whenever I try resetting the hardware device the "COM Port" Jumps to a new "port". So I need to manually change the port in the code frequently.
Is there a way to set a default "COM PORT" in Ubuntu for a serial port device (or) is there a way to automatically detect the "COM PORT" by my program!?
The thing I tried is:
import serial.tools.list_ports
import serial
print('Searching for ports...')
ports=serial.tools.list_ports.comports(include_links=False)
for port in ports:
if port.device=="/dev/ttyACM0" or port.device=="/dev/ttyACM1" or port.device=="/dev/ttyACM2":
ser=serial.Serial(port.device)
break
if ser.isOpen():
ser.close()
ser=serial.Serial(port.device,115200)
ser.flushInput()
ser.flushOutput()
print('Connected to :'+ser.name)
But this code doesn't provide the required output. The code sometimes doesn't select the correct "COM PORT".

i am trying to develop a port scanner in python but my code is not giving any open port give me some suggestions about that?

This is my code it's just starting the scan but it is not completing ,where is the error in it. i need output as port number and port side by side.when i run in command prompt it gives like that,please give suggetions on that
from socket import *
import sys,time
from datetime import datetime
host =''
max_port=100
min_port=1
def scan_host(host,port,r_code=1):
try:
s=socket(AF_INET,SOCK_STREAM)
code=s.connect_ex((host,port))
if code==0:
r_code=code
s.close()
except Exception,e:
pass
return r_code
try:
host=raw_input("Enter Host address:")
except KeyboardInterrupt:
print("\n Application shtdown")
sys.exit(1)
hostip=gethostbyname(host)
print("\n Host:%s IP:%s" %(host,hostip))
print("Scanning Started At %s...\n" %(time.strftime("%H:%M:%S")))
start_time=datetime.now()
for port in range(min_port,max_port):
try:
response=scan_host(host,port)
if response ==0:
print("Port %d: Open" %(port))
except Exception,e:
pass
stop_time=datetime.now()
total_time_duration=stop_time -start_time
print("\n Scanning Finished At %s ..." % (time.strftime("%H:%M:%S")))
print("Scanning Duration:%s..." %(total_time_duration))
print("Have a nice day ...Sergeant Exploiter (Sploit)")
Before using the following port scanner, you may want to check a few things first:
Is the firewall on your computer blocking the port scanner?
Is the device your computer connected to blocking certain ports?
Is the computer you are trying to scan blocking ports with its firewall?
Do you know the correct name of the host that you are trying to scan?
Can you create a server on one computer and connect to it with a client on the other?
If none of the above points are cause for your problem, the program shown below may work for you:
#! /usr/bin/env python3
import argparse
import collections
import itertools
import multiprocessing
import operator
import socket
PURPOSE = 'Scan for open ports on a computer.'
PORTS = range(1 << 16)
POOL_SIZE = 1 << 8
TIMEOUT = 0.01
def main():
"""Get computer to scan, connect with process pool, and show open ports."""
parser = argparse.ArgumentParser(description=PURPOSE)
parser.add_argument('host', type=str, help='computer you want to scan')
host = parser.parse_args().host
with multiprocessing.Pool(POOL_SIZE, socket.setdefaulttimeout, [TIMEOUT]) \
as pool:
results = pool.imap_unordered(test, ((host, port) for port in PORTS))
servers = filter(operator.itemgetter(0), results)
numbers = map(operator.itemgetter(1), servers)
ordered = sorted(numbers)
print(f'Ports open on {host}:', *format_ports(ordered), sep='\n ')
field_names = 'family', 'socket_type', 'protocol', 'canon_name', 'address'
AddressInfo = collections.namedtuple('AddressInfo', field_names)
del field_names
def test(address):
"""Try connecting to the server and return whether or not it succeeded."""
host, port = address
for info in itertools.starmap(AddressInfo, socket.getaddrinfo(host, port)):
try:
probe = socket.socket(info.family, info.socket_type, info.protocol)
except OSError:
pass
else:
try:
probe.connect(info.address)
except OSError:
pass
else:
probe.shutdown(socket.SHUT_RDWR)
return True, port
finally:
probe.close()
return False, port
def format_ports(ports):
"""Convert port numbers into strings and show all associated services."""
if ports:
for port in ports:
try:
service = socket.getservbyport(port)
except OSError:
service = '?'
yield f'{port:<5} = {service}'
else:
yield 'None'
if __name__ == '__main__':
main()

How to read and write from a COM Port using PySerial?

I have Python 3.6.1 and PySerial Installed. I am trying the
I am able to get the list of comports connected. I now want to be able to send data to the COM port and receive responses back. How can I do that? I am not sure of the command to try next.
Code:
import serial.tools.list_ports as port_list
ports = list(port_list.comports())
for p in ports:
print (p)
Output:
COM7 - Prolific USB-to-Serial Comm Port (COM7)
COM1 - Communications Port (COM1)
I see from the PySerial Documentation that the way to open a COM Port is as below:
import serial
>>> ser = serial.Serial('/dev/ttyUSB0') # open serial port
>>> print(ser.name) # check which port was really used
>>> ser.write(b'hello') # write a string
>>> ser.close() # close port
I am running on Windows and I get an error for the following line:
ser = serial.Serial('/dev/ttyUSB0')
This is because '/dev/ttyUSB0' makes no sense in Windows. What can I do in Windows?
This could be what you want. I'll have a look at the docs on writing.
In windows use COM1 and COM2 etc without /dev/tty/ as that is for unix based systems. To read just use s.read() which waits for data, to write use s.write().
import serial
s = serial.Serial('COM7')
res = s.read()
print(res)
you may need to decode in to get integer values if thats whats being sent.
On Windows, you need to install pyserial by running
pip install pyserial
then your code would be
import serial
import time
serialPort = serial.Serial(
port="COM4", baudrate=9600, bytesize=8, timeout=2, stopbits=serial.STOPBITS_ONE
)
serialString = "" # Used to hold data coming over UART
while 1:
# Wait until there is data waiting in the serial buffer
if serialPort.in_waiting > 0:
# Read data out of the buffer until a carraige return / new line is found
serialString = serialPort.readline()
# Print the contents of the serial data
try:
print(serialString.decode("Ascii"))
except:
pass
to write data to the port use the following method
serialPort.write(b"Hi How are you \r\n")
note:b"" indicate that you are sending bytes

Cannot send/receive using Xbee's in API mode (python)

I have two Xbee Pro 900's, each attached to a Raspberry Pi. Both are updated to version 1061 and are set to API Enable with escapes. They also have the same Modem VID of 7FFF. Both Pi's have PySerial and the python-xbee library installed.
Xbee 1(Receiver) has a serial number of 0013A200409A1BB8
Xbee 2(Sender) has a serial number of 0013A200709A1BE9
I've included my code below, which is just sample code I've found online. My issue is that I'm not receiving anything on the appropriate Xbee. I have absolutely no idea what is wrong, I've triple checked the destination address, and both of the Xbee's configuration settings.
Xbee 2 Code(Sender):
#! /usr/bin/python
import time
from xbee import XBee
import serial
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
# Create API object
xbee = XBee(ser,escaped=True)
import pprint
pprint.pprint(xbee.api_commands)
DEST_ADDR_LONG = "\x00\x13\xA2\x00\x40\x9A\x1B\xB8"
# Continuously read and print packets
while True:
try:
print "send data"
xbee.tx_long_addr(frame='0x1', dest_addr=DEST_ADDR_LONG, data='AB')
time.sleep(1)
except KeyboardInterrupt:
break
ser.close()
Xbee 1 Code(Receiver):
#! /usr/bin/python
from xbee import XBee
import serial
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
# Create API object
xbee = XBee(ser,escaped=True)
# Continuously read and print packets
while True:
try:
print "waiting"
response = xbee.wait_read_frame()
print response
except KeyboardInterrupt:
break
ser.close()
When both programs are running, the Tx light on the sending Xbee blinks, but I receive nothing on the receiving Xbee. Is there something I'm missing? Thanks for your time!
Are you using XBee or XBeePro? I had the same problem and this post helped me a lot.
Try to modify the Receiver Code the following way:
import config
import serial
import time
from xbee import ZigBee
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
hv = '0x' + hv
lst.append(hv)
def decodeReceivedFrame(data):
source_addr_long = toHex(data['source_addr_long'])
source_addr = toHex(data['source_addr'])
id = data['id']
samples = data['samples']
options = toHex(data['options'])
return [source_addr_long, source_addr, id, samples]
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
# Open serial port
ser = serial.Serial(PORT, BAUD_RATE)
zb = ZigBee(ser, escaped = True)
while True:
try:
data = zb.wait_read_frame()
decodedData = decodeReceivedFrame(data)
print decodedData
except KeyboardInterrupt:
break
In my case the code above outputs the following:
[['0x00', '0x13', '0xa2', '0x00', '0x40', '0x9b', '0xaf', '0x4e'], ['0x68', '0x3f'], 'rx_io_data_long_addr', [{'adc-0': 524}]]
Here I shared configuration settings for Controller Node (compatible with X-CTU)
Are you sure the XBee modules are in escaped API mode (ATAP=2)? And 9600 baud?
Can you enable a mode in python-xbee to dump all characters in and out?
Have you confirmed the serial wiring is correct? (I see you're using USB, so that's not an issue.)
If you don't have hardware flow control hooked up, make sure the XBee modules have ATD6=0 and ATD7=0 set (disable RTS and CTS) and that python-xbee isn't expecting handshaking.
If you do have hardware flow control configured on the XBee, make sure you've told python-xbee to use it.
Can you use minicom or another serial terminal on the RaspPi to confirm that serial is working? Use minicom on the receiving end to see if you're getting anything at all?
Can you try sending and receiving with the radios connected to a PC instead of the Pi? Sending from the PC to the Pi, or vice-versa?

Categories

Resources