Raspberry PI USB to RS232 adapter Receiving Only Ctrl Chars - python

I'm using a USB to RS232 cable for get communication with a pure rs232 device.
With pyserial lib a got this code running in loopback tx -> rx cable pins.
Setting the port:
def __init__ (self, baudrate,timeout,parity,stopbits,bytesize):
try:
#self.s = serial.Serial(port="'/dev/ttyUSB0'",baudrate=baudrate,timeout=timeout,parity=parity,stopbits=stopbits,bytesize=bytesize)
#self.s = serial.Serial("/dev/ttyUSB0",9600)
self.s=serial.Serial(
"/dev/ttyUSB0",
baudrate=9600,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
writeTimeout = 0,
timeout = 10,
rtscts=False,
dsrdtr=False,
xonxoff=False)
except:
print ("Can't open Serial Port")
traceback.print_exc(file=sys.stdout)
Writing and reading from it:
def write(self,data):
if self.s.isOpen():
try:
self.s.write(data)
self.s.flush()
except:
traceback.print_exc(file=sys.stdout)
print "Error on writing"
else:
print "Port is closed"
def read(self):
receivedData=[]
if self.s.isOpen():
try:
while self.s.inWaiting()> 0:
receivedData.append(self.s.read(1))
return receivedData
except:
traceback.print_exc(file=sys.stdout)
print "Error on Reading"
else:
print "Port is closed"
traceback.print_exc(file=sys.stdout)
I sent 'Carlos'.
And received ['\x03', '\x01', '\x12', '\x0c', '\x0f', '\x13']
It is hex representation of ^C^a^r^l^o^s
I need to know why it is converting chars to control chars?

This is what you would expect if the sending end is using only 5 bits.
First check the settings on the sending device.
If possible, verify the bits are being send with an oscilloscope or logic analyser.
Perhaps the dongle is broken.
Maybe some part of the system has a poor power supply and the final 3 bits are not being detected properly.

After a lot of attempts without any idea about how fix this problem, I bought new cable USB to RS232, it is based on Prolific PL2303 Chipset and it is working properly right now.

Related

Correctly connect to serial Python to avoid ftser2k.sys blue screen

So I'm using the pyserial module to manage connection between my PC and a device.
My code is:
port = 'COM3'
baud = 38400
while is_serial_not_connected:
try:
ser = serial.Serial(port, baud, timeout=None)
is_serial_not_connected = False
print("Serial Connected")
except serial.serialutil.SerialException:
logging.error("Can't find serial")
logging.info("We'll wait other 3 seconds")
time.sleep(3)
if not ser.isOpen():
ser.open()
ser.reset_input_buffer()
ser.reset_output_buffer()
Now, my device continue to stream data via the serial port and if I connect the device to my pc before or after launching my Python software Windows 10 goes in blue screen with error ftser2k.sys: PAGE_FAULT_IN_NONPAGED_AREA
If I have my software running, with the serial cable connected and I start the communication I got no error
I think the issue is that while I'm closing my Python software, the serial driver doesn't really close the communication and when I try to re-launch the software, it automatically starts receiving data saturating some sort of buffers
PS I'm using an USB-RS485-WE-1800-BT cable

pyserial write() writes only the first few bytes

I'm performing reads and writes with pyserial to a serial terminal running on a decawave DWM1001C. The serial connection goes from my Linux laptop to the device over a microUSB cable which also powers the device. The DWM1001C offers the serial connection internally on the chip. The connection is opened at the baudrate of 115200 with 8N1, as specified by the DWN1001C reference manual.
The problem I have is that when I call pyserial's write() on the serial device, I can only write a maximum of 7 characters per write call, sometimes as few as 4. Here's a minimal code to reproduce the issue:
import serial
import sys
import time
dev = "/dev/ttyACM0"
baudrate = 115200
try:
ser = serial.Serial(dev, baudrate, timeout=3)
except Exception as e:
print("Failed opening device: " + dev + ": " + str(e))
sys.exit(1)
try:
# Two CR's are required to open the terminal as the device default to "API" mode
ser.write(b"\r\r")
ser.flush()
time.sleep(2)
# only letters up to f are sent
ser.write(b"abcdefg hijklmn opqrstu vwxyz\n")
ser.flush()
time.sleep(2)
except Exception as e:
print("Failed writing instructions to device: " + str(e))
sys.exit(1)
while True:
try:
line = ser.readline()
if line == None:
continue
except Exception as e:
print("Failed reading from serial: " + str(e))
sys.exit(1)
s = line.decode("utf-8")
print("got data: " + s)
By using the readline() call and by monitoring the serial terminal over minicom, I have verified that only the 4-7 first characters appear in the terminal. Minicom can be used to interact with the serial terminal normally, so I assume minicom does something under the hood that this pyserial code doesn't.
I have a hacky workaround: Every time I perform writes, I split the input data into 4 character chunks and send them one-by-one over write(), then sleep for 0.1 seconds. This seems to work, but is likely about as platform specific as it can be.
The pyserial constructor takes a few different flow control flags and I tried setting each of them on independently. They are:
xonxoff=True
rtscts=True
dsrdtr=True
They didn't seem to do anything. I also tried lowering the baudrate to 57600 to no effect.
What should I read on to understand what's going on?

Python pySerial on Raspberry Pi Zero W: detecting a disconnected serial device

In my project, there's a Raspberry Pi Zero W, linked with Arduino Pro Micro over the serial TX/RX lines (through 5 - 3.3V logic level converter). At power-on, the Arduino starts sending "are you there" command over the serial, until Pi has finished booting and launched a python program that listens on serial port, and it replies with "yes". Then Arduino proceeds with sending regular updates with sensor data.
For some reason not yet understood, the Arduino can disconnect and reboot, while the Pi is still running. And, for some reason, the connection on the Python end is severed in a way that does not raise exception if connection.in_waiting is read.
import serial
import time
ser = serial.Serial('/dev/serial0')
ser.baudrate = 9600
cmd = b''
while True:
time.sleep(1)
print(ser.is_open)
while ser.in_waiting:
ch = ser.read()
if ch == b'\n':
print('New command:', cmd)
cmd = b''
ser.write(b'OK\n')
continue
else:
cmd = cmd + ch
I have tested with this simple code, but in my tests, if I disconnect the Arduino and connect it back, the ser.is_open never is False, and the old connection works just fine also with reconnected Arduino. So, unfortunately I can not exactly replicate the loss of connection scenario when the data stop coming after disconnection. However, in order to investigate further, I'd like to add some monitoring code that would log serial disconnection incidents in file. But is there a way? If connection.is_open is always true, even without Arduino connected, then how one can detect if there is no connection?
The port remains open if there's a disconnection so your example code will loop continuously.
import serial
def connect(port):
return serial.Serial(port, baudrate=9600, timeout=1)
ser = connect('/dev/serial0')
buf = bytearray()
while True:
i = buf.find(b'\n')
if i >= 0:
buf = buf[i + 1:]
ser.write('OK\n')
num_bytes = max(1, min(1024, ser.in_waiting))
data = ser.read(num_bytes)
if data:
buf.extend(data)
else:
# no data to read aka disconnection has occurred
ser = connect('/dev/serial0')
if ser.isOpen():
continue
else:
# could not reconnect
break

Beaglebone Black Wireless: UART isn't reading

I'm trying to have a Beaglebone Black Wireless(debian image 2017-07-01) communicate to another device using UART serial communication. In an example program, the bone waits for the device to send the letter "A", then, upon receiving the right letter, outputs a message and transmits the letter "B". Here is the following program:
import Adafruit_BBIO.UART as UART
import serial
#Enabling the serial ports
UART.setup("UART1")
#Serial setup values
ser = serial.Serial()
ser.port = "/dev/ttyO1"
ser.baudrate = 9600
READ_LEN = 1
ser.close()
rx = ""
while True:
print "Waiting for A... "
ser.open()
rx = ser.read()
ser.close()
if (rx == 'A'):
print "Got it!"
ser.open()
ser.write("B")
ser.close()
break
The program doesn't throw any errors, however, when testing it out with the device, the program gets stuck on the "Waiting for A" line. I have thoroughly checked that all connections are correct and that the other device is sending data. Additionally, the program runs perfectly on an older Beaglebone (debian image 2015-11-12).
Any help into this matter would be greatly appreciated.
config-pin "Whatever Pin You Are Using" uart
example:
config-pin P9.14 uart
Seth

How to check if device is connected Pyserial

I am connecting with my Arduino through a USB port and sending data to it by using PySerial module. At first I can check if the device is connected by using this code:
try:
ser = serial.Serial("COM3", 9600)
except serial.serialutil.SerialException:
print "Arduino not connected"
Now what I want to do is to check periodically if the Arduino is still connected to the computer. I tried ser.isOpen() but this returns true even if the Arduino is disconnected. I would also like to know how to reconnect the device. I mean once you disconnect the device the program can no longer send any data to Arduino.
Most of the answers propose 2 approaches:
In some point of the code, send some sort of message through serial to check if your device is still alive
Start a separate thread and continuously check if the device is alive by opening a communication
The problem with the first solution is that you are not always checking the connection, but only checking in some specific points: this solution isn't very elegant and if badly written could even be not working.
The second solution solves the problem of the first solution, but introduces a new problem: checking the connection, or worst sending a message, in a threaded loop will cause problem or may even interrupt the connection to the device from other functions.
A solution that allows you to constantly check the connection without monopolizing the communication involves the reading of the existing COM:
import serial.tools.list_ports
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
print myports
output:
[(u'COM3', u'Arduino Due Programming Port (COM3)', u'some more data...'),
(u'COM6', u'USB Serial Port (COM6)', u'some more data...'),
(u'COM100', u'com0com - serial port emulator (COM100)', u'some more data...')]
then we save the tuple that contains our port:
arduino_port = [port for port in myports if 'COM3' in port ][0]
then we create a function that checks if this port is still present:
import time
def check_presence(correct_port, interval=0.1):
while True:
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
if arduino_port not in myports:
print "Arduino has been disconnected!"
break
time.sleep(interval)
At last, we run this function as a daemon thread:
import threading
port_controller = threading.Thread(target=check_presence, args=(arduino_port, 0.1,))
port_controller.setDaemon(True)
port_controller.start()
in this way, you'll check each 0.1 secs if the arduino is still connected, and the thread will end when arduino is disconnected or all other activities have ended
You can set a timeout.
import serial
ser = serial
try:
ser = serial.Serial("COM3", 9600, timeout=10)
while ser.read():
print 'serial open'
print 'serial closed'
ser.close()
except serial.serialutil.SerialException:
print 'exception'
Unfortunately, the best way I can find to do this is to try some communication and see if it fails. A pretty safe way would be:
try:
ser.inWaiting()
except:
print "Lost connection!"
You'll probably still want to close the connection with a ser.close() after the connection is lost, although you may need to place that in a "try:except" block also.
import serial
import time
ser = serial.Serial()
ser.braudrate = 115200
ser.port = "/dev/ttyUSB0"
ser.open()
print(ser.name)
if ser.isOpen():
print("serial is open!")
ser.close()
For example to detect ttyUSB0:
import os
x=os.system("ls /dev/ttyUSB0")
if x==0:
print "connected"
else:
print "disconnected"
i suggest to use a python thread class to istantiate a serial connection, in the run methos put your while loop , set an var that you use for kill iy at the end, the second public var that you use for store data if have receive and load data in main method.. soon paste an example
class Arduino():
def __init__(self,Port='/dev/ttyUSB0',Boud=9600,connState=0):
self.parent=self
self.port=Port
self.boud=Boud
self.connState=connState
self.timeount=1
self.ser=None
self.connect()
def connect(self):
try:
self.ser=serial.Serial(self.port,self.boud,timeout=0.0001)
self.connState=1
return [1,'connect']
except:
self.connState=0
return [0,'no hardware found']
def loadData(self):
self.buffer=self.ser.read(1)
if (self.buffer!=''):
try:
print self.buffer
except Exception, e:
pass
ard=Arduino()
while True:
if ard.connState:
ard.loadData()
else:
print "Arduino not found"
break
and start with:
import threading
class ThController( threading.Thread ):
# Override Thread's __init__ method to accept the parameters needed:
def __init__( self,parent):
self.parent = parent
threading.Thread.__init__ ( self )
def run ( self ):
while self.parent.ctrlattive:
j=json.loads(data)
self.parent.data=j

Categories