Pyserial: termios.error: (22, 'Invalid argument') while reading from virtual serial port - python-3.x

Is there any posibility to read from virtual serial ports without mentioned error?
I'm trying to reach data sent from symbol/zebra barcode scanner li4278. Device is working in simple com port emulation mode and it's under /dev/usb/hiddev0 as serial port.
I'm sure that emulation works fine because CuteCom can read from it, and also this simple pyton script works too:
defaultDevice = '/dev/usb/hiddev0'
inDev = open(defaultDevice, 'rb')
while True:
inBytes = inDev.read(1)
for x in inBytes:
print(x)
But anytime I'm trying to read it using pyserial with such a minimal code like this:
with serial.Serial('/dev/usb/hiddev0', timeout=1) as ser:
x = ser.read()
print(x)
the same error occurs: termios.error: (22, 'Invalid argument'). It's like it can't read from virtual serial ports.
And no, setting args to rtscts=True, dsrdtr=True doesn't work.
I have the same '22, invalid argument' error.
Linux Mint 18, 64 bit, Python 3.7, pyserial 3.4.
Anyone knows what's the thing?

Related

Jetson AGX Orin: tty device usable only once before failing

I am using a barcode scanner as part of a project, everything works correctly until I exit the program then I can't communicate anymore with the barcode scanner. This holds true for whatever program I'm running, be it one of my own or just using screen to monitor the transmissions. As soon as I exit, the only way to make the scanner work again is to unplug and replug.
The scanner (this one) is always mounted correctly (usually at /dev/ttyACM0) and communicates by SSI over USB CDC.
I’ve tried monitoring with pyserial’s miniterm and with screen /dev/ttyACM0 9600 but the same problem arises (f.e. screen just says [screen is terminating])
Mind you, everything works well on another computer so I believe it might be an issue with the Jetson rather than the scanner.
In the project I’m trying to run, I use pyserial to interact with the device. Here is an extract of the code to give you an idea of how I use it:
import serial
serial_port = "/dev/ttyACM0"
baud_rate = 9600
with serial.Serial(serial_port, baud_rate, timeout=0.1) as device_serial:
device_serial.flush()
while True:
try:
# read a line from the serial port
barcode_byte_string = device_serial.readline()
if len(barcode_byte_string) > 0:
# convert the byte string to a string and strip the newline character
barcode = barcode_byte_string.decode("utf-8").rstrip()
# publish the barcode to the topic
self.publish_barcode(barcode, serial_port)
except serial.SerialException as e:
# exit with error code 1. This will cause the application to be restarted.
sys.exit(1)
except Exception as e:
break

s.bind((hostMACAddress,port)). OSError: [WinError 10049] The requested address is not valid in its context

I am trying to use the Bluetooth library in python 3 to enable me to allow a robot I am making to communicate with my PC. I have created a Bluetooth server that uses MAC addresses. unfortunately I have hit a halt in my program on this line:
s.bind((hostMACAddress,port))
OSError: [WinError 10049] The requested address is not valid in its context
For some reason it does not seem to like the MAC address (I have checked over the MAC address several times now and it is definitely correct). Personally, I would rather not want to use python 2 as the robot I am using is only compatible with python 3 and by using python 2 the whole idea would not work.
"""
A simple Python script to receive messages from a client over
Bluetooth using Python sockets (with Python 3.3 or above).
"""
import socket
hostMACAddress = 'xx:xx:xx:xx:xx:xx' # The MAC address of a Bluetooth adapter on the server. The server might have multiple Bluetooth adapters.
port = 3 # 3 is an arbitrary choice. However, it must match the port used by the client.
backlog = 1
size = 1024
s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_STREAM, socket.BTPROTO_RFCOMM)
s.bind((hostMACAddress,port))
s.listen(backlog)
try:
client, address = s.accept()
while 1:
data = client.recv(size)
if data:
print(data)
client.send(data)
except:
print("Closing socket")
client.close()
s.close()
Here is the guide I have been following:
https://blog.kevindoran.co/bluetooth-programming-with-python-3/
These lines I have used alternatively to using MAC addresses (I am have tried using both):
hostIPAddress = "x.x.x.x"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((hostIPAddress,22))

Odd behavior with urllib.request.urlopen in Ubuntu 18.04

I have been working through an online class on python with Coursera (this is not homework) and have been having a problem with urllib.request.urlopen for some urls. For the url hardcoded into the code below, the command urllib.request.urlopen(serviceurl, context=ctx).read().decode() times out. If another url is used... say http://www.woot.com is used data is returned.
I have tried this on two separate Ubuntu machines at my location, both running 18.04 (with 3.6.7 which is default) and 3.7.3 via Anaconda.
I have even reinstalled Ubuntu with the same results.
Strangely, if I include a timeout parameter (for example, urllib.request.urlopen(serviceurl, timeout=1, context=ctx).read().decode()), data is returned.
Also, this program runs successfully (regardless of url) with no timeout parameter on a macbook air running 3.6.4
import urllib.request
import ssl
# Ignore SSL certificate errors
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
address = input('Enter Locaton: ')
if len(address) < 1:
serviceurl = 'http://py4e-data.dr-chuck.net/comments_42.xml?'
else:
serviceurl = address
s = urllib.request.urlopen(serviceurl, context=ctx).read().decode()
print(s)
I seem to be the only one having this issue and it has me stumped. I am just beginning to get familiar with python (C, C#, Java are more familiar). Any ideas would be appreciated.
Answered (I think) my own question. Looks like the website does not like IP6 sockets. Was able to trace the hang back to socket.py. First address used in create connection is an IP6 address and port which does not return anything. Adding a timeout caused the code to select the next address and port from the list which was IP4 and that worked. For the time being I disabled IP6 in Ubuntu 18.04 to force IP4 use.

Can not pass OSC data using IMU manufacturer's python2.7 example script

I am working with a high refresh rate IMU (x-IO technologies NGIMU) which outputs all data in osc format. The manufacturer provides the following python script to serve the data on linux platforms ( I am running Ubuntu 16.04)
'''
NGIMU Demo python v2.7 script written by Tom Mitchell (teamxe.co.uk) 2016
Requires pyOSC https://trac.v2.nl/wiki/pyOSC
'''
import socket, OSC, threading, time
# Change this to the NGIMU IP address
send_address = '192.168.1.1', 9000
# Set the NGIMU to send to this machine's IP address
c = OSC.OSCClient()
c.connect(send_address)
msg = OSC.OSCMessage()
msg.setAddress('/wifi/send/ip')
msg.append(str(socket.gethostbyname(socket.gethostname())))
c.send(msg)
c.close()
# Set up receiver
receive_address = '192.168.1.2', 8000
s = OSC.OSCServer(receive_address)
s.addDefaultHandlers()
def sensorsHandler(add, tags, args, source):
print add + str(args)
def quaternionHandler(add, tags, args, source):
print add + str(args)
def batteryHandler(add, tags, args, source):
print add + str(args)
# Add OSC handlers
s.addMsgHandler("/sensors", sensorsHandler)
s.addMsgHandler("/quaternion", quaternionHandler)
s.addMsgHandler("/battery", batteryHandler)
# Start OSCServer
print "\nUse ctrl-C to quit."
st = threading.Thread(target = s.serve_forever)
st.start()
# Loop while threads are running
try :
while 1 :
time.sleep(10)
except KeyboardInterrupt :
print "\nClosing OSCServer."
s.close()
print "Waiting for Server-thread to finish"
st.join()
print "Done"
The IMU hosts its own network which I connect to with the computer that is to receieve the data.
I have installed pyOSC from the location referenced in the script.
When I run the script, no data is delivered, only the message "Use ctrl-C to quit".
All connections seem to take place properly. When the script is running, I can see the udp connection at the correct ip and port using the Ubuntu firewall configuration gui. I have tried disabling the firewall but that had no effect.
Separately, I have used another computer to send udp packets to that ip and port and confirmed their receipt.
To say that I am a coding novice is far too generous. Nonetheless, I need to get this script running. Any help you can offer is greatly appreciated.
The problem is that
socket.gethostbyname(socket.gethostname())
is not setting the correct IP. You should change to
msg.setAddress('/wifi/send/ip')
msg.append('192.168.1.2')

PySerial "better" port names for Linux?

Followup question to this: permanent USB port names? (Linux)
On Windows the port names don't change between actual physical ports. They are along the lines of "COM3", "COM6", etc.
On Linux, if I plug one USB device first , it will be "ttyUSB0" and if I plug the same device second in any other physical port it will be "ttyUSB1". That won't work if I want to, say, have 2 Arduinos connected via Pyserial to the PC.
In the above answer I was shown a way to get an IP-like "serial name". How can I feed that to the PySerial class instead?
An example:
import serial
ser = serial.Serial(port = "/dev/USBNAME", baudrate=9600)
ser.close()
ser.open()
if ser.isOpen():
ser.write("test")

Resources