I'm trying to write a python program which can communicate over a serial interface using PySerial module as follows:
import serial
if __name__ == '__main__':
port = "/dev/tnt0"
ser = serial.Serial(port, 38400)
print ser.name
print ser.isOpen()
x = ser.write('hello')
ser.close()
print "Done!"
But if I execute the above I get the following error:
/dev/tnt0
True
Traceback (most recent call last):
File "/home/root/nested/test.py", line 15, in <module>
x = ser.write('hello')
File "/usr/local/lib/python2.7/dist-packages/serial/serialposix.py", line 518, in write
raise SerialException('write failed: %s' % (v,))
serial.serialutil.SerialException: write failed: [Errno 22] Invalid argument
I referred to the pyserial documentation and according to that this should work without an issue. Please let me know what i'm doing wrong in this.
TIA!
For some reason, in order to use the module tty0tty, you need to open both /dev/tnt0 and /dev/tnt1, or any of the other pairs (e.g /dev/tnt2 and /dev/tnt3).
The code below works:
import time
import serial
def main():
vserial0 = serial.Serial(port='/dev/tnt0', baudrate=9600, bytesize=8, parity=serial.PARITY_EVEN, stopbits=1)
vserial1 = serial.Serial(port='/dev/tnt1', baudrate=9600, bytesize=8, parity=serial.PARITY_EVEN, stopbits=1)
n_bytes = 0
while n_bytes == 0:
vserial0.write('test')
n_bytes = vserial1.inWaiting()
time.sleep(0.05)
print vserial1.read(n_bytes)
if __name__ == '__main__':
main()
/dev/tntX are emulated port pairs, and to perform a successful read or write you need to open both ports from a pair.
Think of it as a pipe - if one end is closed, you will be not able to push the data through.
Related
new to Python but it really makes fun to work with :-)
Using the pyserial lib and works fine so far. BUT...
...is there a way to ignore the following problem: During a serial communication I disconnect the COM-cable for a short time. I got the following errormessage then:
**Traceback (most recent call last):
File "C:\Users\greulich\PycharmProjects\arduino_serial\main.py", line 48, in <module>
functions.receiveWithStartMarkers()
File "C:\Users\greulich\PycharmProjects\arduino_serial\functions.py", line 30, in receiveWithStartMarkers
receivedChar = serialPort.read(1) # read 1 byte
File "C:\Users\greulich\PycharmProjects\arduino_serial\venv\lib\site-packages\serial\serialwin32.py", line 275, in read
raise SerialException("ClearCommError failed ({!r})".format(ctypes.WinError()))
serial.serialutil.SerialException: ClearCommError failed (PermissionError(13, 'Das Gerät erkennt den Befehl nicht.', None, 22))**
My code looks like that:
while serialPort.is_open is True and newData is False:
#try:
receivedChar = serialPort.read(1) # read 1 byte
print(str(date.time()) + ' >>> ' + 'I got the following byte: ' + str(receivedChar))
I opened up port initially in that module:
try:
serialPort = serial.Serial('COM12', 115200)
except:
print('COM-Port not available!')
print('Will exit not the Python program!')
exit() #quits the complete Python program
serialPort.timeout = 3
Is there a way to define kind of a timeout until this error will hit me where the user has the chance to reconnect the cable?
In a nutshell: I want to be able to disconnect the com cable for a short time and connect it again without an error showing :-)
Thanks,
Markus
I have a Raspberry PI 3 and a GSM/GPRS/GNSS HAT.
I want to read the GPS data from the device with Python.
I have used the example code from the documentation, and rewrote it a bit.
It was working for a couple of hours perfectly, but one time when I rebooted the Raspberry(I have rebooted it before and it was working fine) it started throwing this after a couple of successful reads:
Traceback (most recent call last):
File "/home/ubuntu/gps.py", line 90, in listenForGpsInfo
while ser.inWaiting() > 0:
File "/usr/lib/python3/dist-packages/serial/serialutil.py", line 594, in inWaiting
return self.in_waiting
File "/usr/lib/python3/dist-packages/serial/serialposix.py", line 531, in in_waiting
s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
OSError: [Errno 5] Input/output error
here is my code:
def listenForGpsInfo(callback):
ser = serial.Serial("/dev/ttyS0",baudrate=115200)
W_buff = [b"AT+CGNSPWR=1\r\n", b"AT+CGNSSEQ=\"RMC\"\r\n", b"AT+CGNSINF\r\n", b"AT+CGNSURC=2\r\n", b"AT+CGNSTST=1\r\n"]
ser.write(W_buff[0])
ser.flushInput()
data = ""
num = 0
while True:
time.sleep(utils.GPS_INTERVAL_IN_SECONDS)
try:
while ser.inWaiting() > 0:
data += ser.read(ser.inWaiting()).decode()
print(data)
if data != "":
if num < len(W_buff)-1:
print(num)
ser.write(W_buff[num+1])
num =num +1
else:
ser.write(W_buff[2])
if "+CGNSINF" in data:
data = str(data)
gpsInfo = parseGpsData(findInfoLine(data))
if(gpsInfo is not None):
callback(gpsInfo)
data = ""
except Exception as e:
if ser != None:
ser.close()
traceback.print_exc()
listenForGpsInfo(callback)
return
Here is the documentation of the serial commands: https://www.waveshare.com/w/upload/3/3d/SIM868_GNSS_Application_Note_V1.00.pdf
I tried a lot of things, but I couldn't solve it.
Couple of things I have tried:
Restarting the device
Detaching and Attaching the shield
Only sending the AT+CGNSPWR=1\r\n and the AT+CGNSINF\r\n commands
chmod 666 /dev/ttyS0
I had ubuntu on the raspberry and when I installed raspberry os the error went away.
How could I make an if/else condition about the status of myAarduino? If the status of my Arduino is connected, I want to have a Connected Message. If not, message is Disconnected.
import serial
serialTransferRate = 115200
arduinoPort = '/dev/tty.usbmodem411'
def connectToArduino():
arduino = serial.Serial(arduinoPort, serialTransferRate)
if(arduino.timeout == None):
print ("connected")
else:
print ("disconnected")
arduino = connectToArduino()
The error code below:
File "python", line 12, in <module>
File "python", line 6, in connectToArduino
SerialException: [Errno 2] could not open port /dev/tty.usbmodem411: [Errno
2] No such file or directory: '/dev/tty.usbmodem411'
The indentation should be like this, also you must use == for a comparison in an if statement and not = (which would be for assigning a value):
def connectToArduino():
try:
arduino = serial.Serial(arduinoPort, serialTransferRate)
except:
print 'disconnected'
else:
print 'connected'
arduino = connectToArduino()
The indentation in python is essential. Only things that would be placed in {} in other languages (e.g. C/C++) can and must be indented. If you indent just random code there will be the error message: unexpected indentation.
Using Python 3.3 and pySerial for serial communications.
I'm trying to write a command to my COM PORT but the write method won't take my string. (Most of the code is from here Full examples of using pySerial package
What's going on?
import time
import serial
ser = serial.Serial(
port='\\\\.\\COM4',
baudrate=115200,
parity=serial.PARITY_ODD,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
if ser.isOpen():
ser.close()
ser.open()
ser.isOpen()
ser.write("%01#RDD0010000107**\r")
out = ''
# let's wait one second before reading output (let's give device time to answer)
time.sleep(1)
while ser.inWaiting() > 0:
out += ser.read(40)
if out != '':
print(">>" + out)
ser.close()
Error is at ser.write("%01#RDD0010000107**\r") where it gets
Traceback is like this
data = to_bytes(data)
b.append(item)
TypeError: an integer is required.
It turns out that the string needed to be turned into a bytearray and to do this I editted the code to
ser.write("%01#RDD0010000107**\r".encode())
This solved the problem
You have found the root cause. Alternately do like this:
ser.write(bytes(b'your_commands'))
I had the same "TypeError: an integer is required" error message when attempting to write.
Thanks, the .encode() solved it for me.
I'm running python 3.4 on a Dell D530 running 32 bit Windows XP Pro.
I'm omitting the com port settings here:
>>>import serial
>>>ser = serial.Serial(5)
>>>ser.close()
>>>ser.open()
>>>ser.write("1".encode())
1
>>>
I am trying to run a python file from the command line with a single parameter in Ubuntu 12.04. The program works if I simply run it from the IDE and pass the parameter in the code. However, if I call 'python readFromSerial1.py 3' in the command prompt, I get:
Traceback (most recent call last):
File "readFromSerial1.py", line 62, in <module>
main()
File "readFromSerial1.py", line 6, in main
readDataFromUSB(time)
File "readFromSerial1.py", line 9, in readDataFromUSB
import usb.core
ImportError: No module named usb.core
I'm a little confused as the module imports correctly if I run from the IDE. I download the pyUSB module and extracted it (its filename is pyusb-1.0.0a3). I then copied this file into
/usr/local/lib/python2.7/site-packages/. Is that the correct procedure? I have a feeling the issue is due to python simply not being able to find the usb module and I need to put it in the correct location. My code is below, and any help would be greatly appreciated:
readFromSerial1.py
import sys
def main():
time = sys.argv[1]
#time = 1
readDataFromUSB(time)
def readDataFromUSB(time):
import usb.core
#find device
dev = usb.core.find(idVendor=0x099e, idProduct=0x0001) #GPS info
#Was the device found?
if dev is None:
raise ValueError('Device not found')
else:
print "Device found!"
#Do this to avoid 'Errno16: Resource is busy'
if dev.is_kernel_driver_active(0):
try:
dev.detach_kernel_driver(0)
except usb.core.USBError as e:
sys.exit("Could not detach kernel driver: %s" % str(e))
#Sets default config
dev.set_configuration()
#Gets default endpoint
endpoint = dev[0][(0,0)][0]
writeObject = open("InputData.txt", "w")
#iterate for time purposes
for i in range(0, (time*6)): #sys.argv is command line variable for time input
data = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, 0, 100000)
sret = ''.join([chr(x) for x in data])
writeObject.write(sret);
print sret
'''
newStr = ''.join(sret[7:14])
compareStr = ",*4F"
if (newStr == compareStr):
print "The GPS is not reading in any values right now. Try going somewhere else with better reception."
else:
print sret[7:14]
'''
writeObject.close()
main()